a2a_agent.go

Overview

This file implements a remote agent interface using the Agent-To-Agent (A2A) protocol, enabling communication with agents running in separate processes or hosts. It provides a proxy agent that translates local agent invocation context sessions into A2A protocol messages, sends these messages over the network, and streams back the remote agent's responses as session events. This allows seamless integration of remote agents within the local agent framework while abstracting networking and protocol details.

The core functionality includes:

This file implements the remote agent proxy as an instance of agent.Agent, conforming to the local agent lifecycle and invocation model.


Types and Functions

A2AConfig

type A2AConfig struct {
    Name               string
    Description        string
    AgentCard          *a2a.AgentCard
    AgentCardSource    string
    CardResolveOptions []agentcard.ResolveOption
    ClientFactory      *a2aclient.Factory
    MessageSendConfig  *a2a.MessageSendConfig
}

Description:
Configuration struct to describe and configure a remote A2A agent.

Fields:

Usage Example:

cfg := A2AConfig{
    Name: "RemoteLLMAgent",
    AgentCardSource: "https://example.com/agent_card.json",
    MessageSendConfig: &a2a.MessageSendConfig{ /* ... */ },
}
agent, err := NewA2A(cfg)

NewA2A

func NewA2A(cfg A2AConfig) (agent.Agent, error)

Description:
Factory function that creates a remote A2A agent implementing the agent.Agent interface. It requires either a resolved AgentCard or an AgentCardSource URL/path to function.

Parameters:

Returns:

Usage:
Use this function to instantiate and register a remote agent proxy that delegates invocations via the A2A protocol.


Type a2aAgent

type a2aAgent struct {
    resolvedCard *a2a.AgentCard
}

Description:
Internal struct implementing the remote agent logic. Holds the resolved agent card to avoid repeated resolution.


Method a2aAgent.run

func (a *a2aAgent) run(ctx agent.InvocationContext, cfg A2AConfig) iter.Seq2[*session.Event, error]

Description:
Runs the remote agent invocation. This method performs the following steps:

  1. Resolves the remote agent's agent card if not already done.

  2. Creates an A2A client to communicate with the remote agent.

  3. Constructs an A2A message from the invocation context's session events.

  4. Sends the message using streaming RPC and receives streamed A2A events.

  5. Converts incoming A2A events into session events and yields them.

  6. Handles errors by yielding special error events.

Parameters:

Returns:
A generator function that yields session events or errors, supporting asynchronous streaming of remote agent responses.

Usage:
This method is invoked internally when the agent is run via the ADK agent lifecycle.


resolveAgentCard

func resolveAgentCard(ctx agent.InvocationContext, cfg A2AConfig) (*a2a.AgentCard, error)

Description:
Resolves the remote agent's AgentCard metadata either by:

Parameters:

Returns:
The resolved AgentCard or an error if resolution or parsing fails.

Important Implementation Detail:
Local file-based resolution reads the entire file and unmarshals JSON into an a2a.AgentCard pointer.


newMessage

func newMessage(ctx agent.InvocationContext) (*a2a.Message, error)

Description:
Constructs a new A2A message from the invocation context’s session events. It inspects the session event history to:

Parameters:

Returns:

Usage:
Called internally before sending a message to the remote agent.


toErrorEvent

func toErrorEvent(ctx agent.InvocationContext, err error) *session.Event

Description:
Creates a session event representing an error state, embedding the error message in the event and custom metadata. This event is yielded to signal problems in remote communication or invocation.

Parameters:

Returns:
A session event containing the error details.


updateCustomMetadata

func updateCustomMetadata(event *session.Event, request *a2a.MessageSendParams, response a2a.Event)

Description:
Augments a session event's custom metadata with serialized forms of the A2A request and response messages. This aids debugging and telemetry by preserving raw protocol data.

Parameters:

Implementation Detail:
Uses a converter utility to transform requests into map structures, handling serialization errors gracefully.


destroy

func destroy(client *a2aclient.Client)

Description:
Safely destroys the A2A client, ignoring destruction errors (with a TODO note to add logging).

Parameters:


Important Implementation Details


Interaction with Other Parts of the System


Visual Diagram

sequenceDiagram
participant LocalA2AAgent as Local A2A Agent
participant Client as A2A Client
participant RemoteAgent as Remote Agent Server
LocalA2AAgent->>LocalA2AAgent: Resolve AgentCard (URL/File)
LocalA2AAgent->>Client: Create client from AgentCard
LocalA2AAgent->>LocalA2AAgent: Convert InvocationContext events to A2A Message
LocalA2AAgent->>Client: SendStreamingMessage(Message)
Client->>RemoteAgent: Transmit A2A Message (gRPC/HTTP)
RemoteAgent->>RemoteAgent: Process message, generate events
RemoteAgent->>Client: Stream A2A Events (responses)
Client->>LocalA2AAgent: Receive streamed events
LocalA2AAgent->>LocalA2AAgent: Convert A2A Events to Session Events
LocalA2AAgent->>Caller: Yield session events (stream)

This sequence diagram illustrates the lifecycle of an invocation through the remote A2A agent proxy, showing agent card resolution, client creation, message sending, event streaming, conversion, and yielding back to the invoking caller.


References to Related Topics

This file is a core component enabling distributed multi-agent orchestration by bridging local invocation with remote agent communication through the A2A protocol.