a2a

package
v0.16.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package a2a provides shared types for the Agent-to-Agent (A2A) protocol.

Index

Constants

View Source
const (
	ErrCodeParseError     = -32700
	ErrCodeInvalidRequest = -32600
	ErrCodeMethodNotFound = -32601
	ErrCodeInvalidParams  = -32602
	ErrCodeInternal       = -32603
)

JSON-RPC 2.0 error codes.

Variables

View Source
var (
	// ErrPartKindMissing is returned when a Part has empty Kind. This
	// is the canonical "you sent `type` instead of `kind`" signal —
	// the wrapped error message names the likely mistake when the
	// part has content despite the missing discriminator.
	ErrPartKindMissing = errors.New("part kind is required")

	// ErrPartKindUnknown is returned when a Part has a Kind value the
	// runtime doesn't recognize. A2A 0.3.0 defines text / data / file.
	ErrPartKindUnknown = errors.New("part kind is not one of text/data/file")

	// ErrMessageRoleMissing is returned when a Message has no role.
	ErrMessageRoleMissing = errors.New("message role is required")

	// ErrMessagePartsEmpty is returned when a Message has zero parts.
	// Some A2A clients emit empty parts arrays for heartbeat-style
	// pings; Forge rejects those at the entry point so the executor
	// never sees a message with nothing to interpret.
	ErrMessagePartsEmpty = errors.New("message parts must contain at least one element")
)

Errors returned by Validate. Exposed as sentinels so callers can branch on them (e.g. emit a specific audit-event reason code or log a dedicated counter) without parsing error strings.

Functions

This section is empty.

Types

type AgentCapabilities

type AgentCapabilities struct {
	Streaming              bool `json:"streaming,omitempty"`
	PushNotifications      bool `json:"pushNotifications,omitempty"`
	StateTransitionHistory bool `json:"stateTransitionHistory,omitempty"`
}

AgentCapabilities declares optional A2A features an agent supports.

type AgentCard

type AgentCard struct {
	// Name is the human-readable agent name. Required.
	Name string `json:"name"`

	// Description is the agent's one-line summary. Optional in the
	// spec, but Forge always populates it.
	Description string `json:"description,omitempty"`

	// URL is the agent's primary service endpoint (the base URL where
	// the JSON-RPC and REST handlers live). Required.
	URL string `json:"url"`

	// Version is the agent's semantic version string (e.g. "0.1.0").
	// Required by A2A 0.3.0. Forge sources this from forge.yaml's
	// version field (or the build-time agent.json's version).
	Version string `json:"version"`

	// ProtocolVersion pins the A2A protocol version this card claims
	// to conform to. Forge always emits "0.3.0".
	ProtocolVersion string `json:"protocolVersion"`

	// DefaultInputModes lists the MIME types the agent accepts on
	// message parts when a skill doesn't override them. A2A 0.3.0
	// requires at least one entry. Forge defaults to text/plain +
	// application/json.
	DefaultInputModes []string `json:"defaultInputModes"`

	// DefaultOutputModes lists the MIME types the agent emits on
	// message parts when a skill doesn't override them. Required.
	DefaultOutputModes []string `json:"defaultOutputModes"`

	// Skills lists the agent's discoverable capabilities. Each entry
	// maps to an A2A AgentSkill object.
	Skills []Skill `json:"skills,omitempty"`

	// Capabilities declares optional A2A features the agent supports.
	Capabilities *AgentCapabilities `json:"capabilities,omitempty"`

	// SecuritySchemes maps a scheme name to its definition. Mirrors the
	// OpenAPI 3.1 securitySchemes shape per A2A 0.3.0. Forge derives
	// these from the configured auth chain (static_token → httpBearer,
	// oidc → openIdConnect, etc.).
	SecuritySchemes map[string]*SecurityScheme `json:"securitySchemes,omitempty"`

	// Security is the list of accepted security requirements. Each
	// entry is a map of scheme name → required scopes (empty array for
	// schemes that don't use scopes). Per OpenAPI semantics, the
	// outer list is OR (any one entry suffices), the inner map is AND.
	Security []map[string][]string `json:"security,omitempty"`

	// Provider identifies the organization publishing the agent.
	// Optional.
	Provider *AgentProvider `json:"provider,omitempty"`

	// DocumentationURL is a link to the agent's external docs. Optional.
	DocumentationURL string `json:"documentationUrl,omitempty"`

	// IconURL is a link to an icon for UI display. Optional.
	IconURL string `json:"iconUrl,omitempty"`
}

AgentCard describes an agent's capabilities for discovery.

The serialized JSON shape conforms to the Agent2Agent (A2A) Protocol 0.3.0 Agent Card specification:

https://github.com/google/a2a-spec

Forge serves the card at /.well-known/agent-card.json (the spec's canonical path). The legacy /.well-known/agent.json path is also served for backward compatibility and emits a Deprecation response header — that alias will be removed in a future release.

Forge-internal fields (egress, denied_tools, trust hints) live in agentspec.AgentSpec and are intentionally NOT serialized into the Agent Card. The card carries only what the A2A spec defines.

type AgentProvider

type AgentProvider struct {
	Organization string `json:"organization,omitempty"`
	URL          string `json:"url,omitempty"`
}

AgentProvider identifies the organization publishing the agent.

type Artifact

type Artifact struct {
	Name        string `json:"name,omitempty"`
	Description string `json:"description,omitempty"`
	Parts       []Part `json:"parts"`
}

Artifact is a named output produced by an agent task.

type CancelTaskParams

type CancelTaskParams struct {
	ID     string `json:"id"`
	Reason string `json:"reason,omitempty"`
}

CancelTaskParams are the parameters for tasks/cancel.

Reason is optional. When set, it classifies why the orchestrator (or operator) is cancelling — see runtime.CancellationReason for the documented values. Unknown reason strings are accepted and forwarded to the audit pipeline verbatim; the value flows straight through to the invocation_cancelled audit event's fields.reason. Absent reason resolves to external_signal at the runtime boundary. See issue #88 / FWS-4.

type FileContent

type FileContent struct {
	Name     string `json:"name,omitempty"`
	MimeType string `json:"mimeType,omitempty"`
	URI      string `json:"uri,omitempty"`
	Bytes    []byte `json:"bytes,omitempty"`
}

FileContent holds the contents or reference for a file part.

type GetTaskParams

type GetTaskParams struct {
	ID string `json:"id"`
}

GetTaskParams are the parameters for tasks/get.

type JSONRPCError

type JSONRPCError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Data    any    `json:"data,omitempty"`
}

JSONRPCError carries error information in a JSON-RPC response.

type JSONRPCRequest

type JSONRPCRequest struct {
	JSONRPC string          `json:"jsonrpc"`
	ID      any             `json:"id,omitempty"`
	Method  string          `json:"method"`
	Params  json.RawMessage `json:"params,omitempty"`
}

JSONRPCRequest is an incoming JSON-RPC 2.0 request.

type JSONRPCResponse

type JSONRPCResponse struct {
	JSONRPC string        `json:"jsonrpc"`
	ID      any           `json:"id,omitempty"`
	Result  any           `json:"result,omitempty"`
	Error   *JSONRPCError `json:"error,omitempty"`
}

JSONRPCResponse is an outgoing JSON-RPC 2.0 response.

func NewErrorResponse

func NewErrorResponse(id any, code int, msg string) *JSONRPCResponse

NewErrorResponse creates an error JSON-RPC 2.0 response.

func NewResponse

func NewResponse(id any, result any) *JSONRPCResponse

NewResponse creates a successful JSON-RPC 2.0 response.

type Message

type Message struct {
	Role    MessageRole `json:"role"`
	Parts   []Part      `json:"parts"`
	Summary string      `json:"summary,omitempty"`
}

Message is a single conversational turn in the A2A protocol.

Summary, when set, is a short LLM-generated synopsis of the agent's full response. Channel adapters prefer it over head-truncating the verbose body when an inline-friendly message is needed. Empty for short responses where the full text already fits inline.

func (Message) Validate

func (m Message) Validate() error

Validate reports whether the Message conforms to the A2A 0.3.0 shape. Role must be non-empty, Parts must be non-empty, and every part must Validate cleanly. The first failing part's error is returned (wrapped with its index) so the caller can name the offending position in their HTTP / JSON-RPC error message.

type MessageRole

type MessageRole string

MessageRole indicates who produced a message.

const (
	MessageRoleUser  MessageRole = "user"
	MessageRoleAgent MessageRole = "agent"
)

type OAuthFlow

type OAuthFlow struct {
	AuthorizationURL string            `json:"authorizationUrl,omitempty"`
	TokenURL         string            `json:"tokenUrl,omitempty"`
	RefreshURL       string            `json:"refreshUrl,omitempty"`
	Scopes           map[string]string `json:"scopes,omitempty"`
}

OAuthFlow describes one OAuth 2.0 flow.

type OAuthFlows

type OAuthFlows struct {
	Implicit          *OAuthFlow `json:"implicit,omitempty"`
	Password          *OAuthFlow `json:"password,omitempty"`
	ClientCredentials *OAuthFlow `json:"clientCredentials,omitempty"`
	AuthorizationCode *OAuthFlow `json:"authorizationCode,omitempty"`
}

OAuthFlows describes the OAuth 2.0 flows supported by an auth scheme. Each field describes one flow; at least one must be populated.

type Part

type Part struct {
	Kind PartKind     `json:"kind"`
	Text string       `json:"text,omitempty"`
	Data any          `json:"data,omitempty"`
	File *FileContent `json:"file,omitempty"`
}

Part is a flat union struct representing a piece of message content. Exactly one of Text, Data, or File should be set, indicated by Kind.

func NewDataPart

func NewDataPart(data any) Part

NewDataPart creates a Part containing structured data.

func NewFilePart

func NewFilePart(file FileContent) Part

NewFilePart creates a Part referencing a file.

func NewTextPart

func NewTextPart(text string) Part

NewTextPart creates a Part containing text content.

func (Part) Validate

func (p Part) Validate() error

Validate reports whether the Part conforms to the A2A 0.3.0 shape.

The most common failure — and the one this method was added to surface clearly — is a Part that omits `kind`. encoding/json silently drops unknown fields, so a client sending the pre-0.3.0 `type` discriminator gets a Part with Kind == "" and a populated content field (Text / Data / File). Without explicit validation the executor receives a part it can't classify and the LLM responds with something like "It looks like your message didn't come through" — confusing the caller about what actually went wrong. See issue #119.

The returned error wraps the sentinel (ErrPartKindMissing or ErrPartKindUnknown) so callers can branch on the cause; the wrapped message names the likely mistake when content is present.

type PartKind

type PartKind string

PartKind discriminates the content type of a Part.

const (
	PartKindText PartKind = "text"
	PartKindData PartKind = "data"
	PartKindFile PartKind = "file"
)

type SecurityScheme

type SecurityScheme struct {
	// Type is one of: "http", "apiKey", "openIdConnect", "oauth2",
	// "mutualTLS".
	Type string `json:"type"`

	// Description is an optional human-readable explanation.
	Description string `json:"description,omitempty"`

	// http: Scheme is the HTTP auth scheme — typically "bearer" or
	// "basic". For "http" Type only.
	Scheme string `json:"scheme,omitempty"`

	// http (bearer): BearerFormat is a hint about the token format
	// (e.g. "JWT").
	BearerFormat string `json:"bearerFormat,omitempty"`

	// apiKey: In identifies where the API key is sent — "header",
	// "query", or "cookie".
	In string `json:"in,omitempty"`

	// apiKey: Name is the name of the header/query/cookie that carries
	// the key. For "apiKey" Type only.
	Name string `json:"name,omitempty"`

	// openIdConnect: OpenIDConnectURL is the OIDC discovery document
	// URL (issuer + /.well-known/openid-configuration).
	OpenIDConnectURL string `json:"openIdConnectUrl,omitempty"`

	// oauth2: Flows describes the supported OAuth 2.0 flows.
	Flows *OAuthFlows `json:"flows,omitempty"`
}

SecurityScheme describes one authentication mechanism advertised in the Agent Card. The shape mirrors the OpenAPI 3.1 Security Scheme object per A2A 0.3.0 §6.5. Only one of the type-specific groupings (Bearer, ApiKey, OpenIDConnect, OAuth2) is populated per instance.

type SendTaskParams

type SendTaskParams struct {
	ID      string  `json:"id"`
	Message Message `json:"message"`
}

SendTaskParams are the parameters for tasks/send and tasks/sendSubscribe.

type Skill

type Skill struct {
	// ID is a slug-format identifier unique within the agent.
	ID string `json:"id"`

	// Name is the human-readable skill name.
	Name string `json:"name"`

	// Description is the skill's one-line summary.
	Description string `json:"description,omitempty"`

	// Tags is a free-form classification list (category, capability
	// labels, etc.). A2A 0.3.0 makes this required; Forge always
	// populates with at least one entry (derived from SKILL.md
	// frontmatter's `category` or `tags` list).
	Tags []string `json:"tags"`

	// Examples is an optional list of example prompts that exercise
	// this skill. Used by A2A clients to surface the skill in a UI.
	Examples []string `json:"examples,omitempty"`

	// InputModes overrides AgentCard.DefaultInputModes for this skill
	// only. Optional.
	InputModes []string `json:"inputModes,omitempty"`

	// OutputModes overrides AgentCard.DefaultOutputModes for this skill
	// only. Optional.
	OutputModes []string `json:"outputModes,omitempty"`
}

Skill describes a discrete capability an agent exposes — the A2A AgentSkill object.

type Task

type Task struct {
	ID        string         `json:"id"`
	Status    TaskStatus     `json:"status"`
	History   []Message      `json:"history,omitempty"`
	Artifacts []Artifact     `json:"artifacts,omitempty"`
	Metadata  map[string]any `json:"metadata,omitempty"`
}

Task represents an A2A task exchanged between agents.

type TaskState

type TaskState string

TaskState represents the possible states of an A2A task.

const (
	TaskStateSubmitted     TaskState = "submitted"
	TaskStateWorking       TaskState = "working"
	TaskStateCompleted     TaskState = "completed"
	TaskStateFailed        TaskState = "failed"
	TaskStateCanceled      TaskState = "canceled"
	TaskStateInputRequired TaskState = "input-required"
	TaskStateAuthRequired  TaskState = "auth-required"
	TaskStateRejected      TaskState = "rejected"
)

type TaskStatus

type TaskStatus struct {
	State   TaskState `json:"state"`
	Message *Message  `json:"message,omitempty"`
}

TaskStatus holds the current state of a task along with an optional message.

type TaskStore

type TaskStore struct {
	// contains filtered or unexported fields
}

TaskStore is a thread-safe in-memory store for A2A tasks.

func NewTaskStore

func NewTaskStore() *TaskStore

NewTaskStore creates an empty TaskStore.

func (*TaskStore) Get

func (s *TaskStore) Get(id string) *Task

Get returns a deep copy of the task with the given ID, or nil if not found.

func (*TaskStore) Put

func (s *TaskStore) Put(t *Task)

Put stores a task. It overwrites any existing task with the same ID.

func (*TaskStore) SetArtifacts

func (s *TaskStore) SetArtifacts(id string, artifacts []Artifact) bool

SetArtifacts replaces the artifacts for an existing task. Returns false if the task does not exist.

func (*TaskStore) UpdateStatus

func (s *TaskStore) UpdateStatus(id string, status TaskStatus) bool

UpdateStatus updates the status of an existing task. Returns false if the task does not exist.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL