Documentation
¶
Overview ¶
Package a2a provides shared types for the Agent-to-Agent (A2A) protocol.
Index ¶
- Constants
- Variables
- type AgentCapabilities
- type AgentCard
- type AgentProvider
- type Artifact
- type CancelTaskParams
- type FileContent
- type GetTaskParams
- type JSONRPCError
- type JSONRPCRequest
- type JSONRPCResponse
- type Message
- type MessageRole
- type OAuthFlow
- type OAuthFlows
- type Part
- type PartKind
- type SecurityScheme
- type SendTaskParams
- type Skill
- type Task
- type TaskState
- type TaskStatus
- type TaskStore
Constants ¶
const ( ErrCodeParseError = -32700 ErrCodeInvalidRequest = -32600 ErrCodeMethodNotFound = -32601 ErrCodeInvalidParams = -32602 ErrCodeInternal = -32603 )
JSON-RPC 2.0 error codes.
Variables ¶
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 ¶
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) PromptText ¶ added in v0.18.1
PromptText projects a message's parts into the single string the LLM sees as the turn's content. Text parts are included verbatim; each data part is appended as a fenced JSON block (capped at dataPartProjectionCap, rune-safe) so structured input carried in a data part — e.g. a workflow step's output dispatched with no text part — still reaches the model instead of yielding an empty prompt (#410). File parts are not projected (their bytes/URIs aren't prompt text).
This is the single source of truth for "what the model sees": the executor's prompt builder AND the inbound guardrail / intent-alignment scanners all go through it, so a data part can never reach the LLM while bypassing the security checks.
func (Message) Validate ¶
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 ¶
NewDataPart creates a Part containing structured data.
func NewFilePart ¶
func NewFilePart(file FileContent) Part
NewFilePart creates a Part referencing a file.
func NewTextPart ¶
NewTextPart creates a Part containing text content.
func (Part) Validate ¶
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 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 ¶
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" // TaskStateDeferred (governance R4c / #211): the executor paused // mid-task awaiting an out-of-band decision (typically human // approval for a high-risk action). Distinct from // `input-required` (which needs more input FROM the user) and // `auth-required` (which needs step-up auth per R4b). A deferred // task is resolved by `POST /tasks/{id}/decisions`; on timeout, // it auto-transitions to `failed` with a deferred-timeout audit. // See docs/security/defer-decisions.md. TaskStateDeferred TaskState = "deferred" )
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 (*TaskStore) SetArtifacts ¶
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.