跳到主要内容

协议参考

本文档描述 iac-code server 暴露的 A2A 1.0 接口面,以及 iac-code a2a-client call 使用的 Phase 1 client 行为。准确的 CLI 选项请参阅 命令参考

生命周期概览

典型 A2A 交互遵循以下流程:

GET Agent Card -> SendMessage or SendStreamingMessage -> GetTask / follow-up / CancelTask
  1. 发现 — 获取 /.well-known/agent-card.json
  2. 发送 — 向 / 上的 JSON-RPC 端点提交文本消息。
  3. 流式接收 — 接收 TaskMessageTaskStatusUpdateEvent payloads。
  4. 继续 — 使用相同 contextId 发送后续消息。
  5. 取消或查询 — 使用 CancelTaskGetTaskListTasks

Agent Card

Agent Card 可通过以下位置获取:

GET /.well-known/agent-card.json

重要字段:

字段含义
nameiac-codeAgent 名称
supportedInterfaces[0].protocolBindingJSONRPC传输绑定
supportedInterfaces[0].protocolVersion1.0A2A 协议版本
supportedInterfaces[0].urlhttp://<host>:<port>/JSON-RPC 端点
capabilities.streamingtrue支持流式任务更新
capabilities.pushNotificationsfalsetrue配置了 push-notifications: true 时为 true
capabilities.extendedAgentCardtrue已认证调用方可以请求扩展运行时细节
capabilities.extensionsurn:iac-code:a2a:artifact-metadata:v1用于工具状态和已存储 artifact 元数据的可选 iac-code 元数据命名空间
defaultInputModestext、JSON、YAML、image、audio 和 binary MIME types接受的输入 MIME 模式
defaultOutputModes["text/plain"]仅文本输出

Agent Card 响应包含 Cache-Control: public, max-age=60ETagLast-Modified。客户端可以发送 If-None-Match,当 card 未更改时会收到 304 Not Modified

公布的技能:

技能 ID用途
iac_generation根据自然语言生成 Alibaba Cloud ROS 和 Terraform 模板
iac_review检查 IaC 模板并建议修复
aliyun_ros_operations协助 Alibaba Cloud ROS stack 工作流
terraform_ros_conversion使用 bundled skill resources 协助 Terraform 到 ROS 转换

启用认证后,Agent Card 会公布已配置的安全方案:

方案公布时机
bearerAuth设置了 tokenIACCODE_A2A_HTTP_TOKEN
basicAuth同时设置了 Basic username 和 password
apiKeyAuth设置了 api-keyIACCODE_A2A_API_KEY

路由

路由方法描述
/healthGET返回 {"status":"healthy"}
/.well-known/agent-card.jsonGET返回 Agent Card
/POST处理 A2A JSON-RPC 请求
REST 路由mixedcreate_rest_routes 注册的 A2A SDK REST 路由

Phase 1 Client 和传输说明

默认的可互操作 Phase 1 传输是基于 HTTP 的 JSON-RPC。HTTP 模式还会为 SDK REST 路由公布 HTTP+JSON

服务器还提供 stdio、Unix sockets、WebSocket、官方 gRPC、gRPC JSON-RPC envelope 和 Redis Streams 的可选传输。stdio、Unix sockets、WebSocket、gRPC JSON-RPC 和 Redis Streams 是自定义 JSON-RPC 传输。官方 gRPC 公布为 grpc,并需要可选 gRPC 依赖。

内置客户端在消息调用前使用 Agent Card 发现(GET /.well-known/agent-card.json),选择第一个已公布且可运行的 supportedInterfaces[].url,然后使用 A2A-Version: 1.0SendMessage 等 A2A 1.0 方法名发送 JSON-RPC 请求。

push-notifications: true 启用 A2A 推送通知配置方法和终态投递。

Agent Card 签名使用 A2A SDK 签名工具,并发出标准 AgentCardSignature JWS 字段。对称密钥模式使用 HS256;验证可以通过 protected-header kid 选择已配置 secret、本地 octet-key JWKS 或远程 JWKS URL。Phase 1 未实现服务器端非对称签名和自动密钥轮换。

Phase 1 不支持行为的规范列表请参阅 A2A 协议

推送通知投递后端

iac-code a2a --config a2a-server.yml 支持两种推送投递队列:

  • push-queue: local-file 将 jobs 存储在 A2A 持久化目录下方,适用于本地单节点使用。
  • push-queue: redis-streams 将 jobs 存储在 Redis Streams 中,并通过 Redis consumer group 协调 workers。

Redis 后端推送投递需要可选的 a2a-redis extra,并且是至少一次投递。Callback 接收方应以幂等方式处理任务更新,因为 worker 崩溃、lease 过期、重连或重试竞争后,一个 job 可能会再次投递。

常用 Redis 选项:

push-notifications: true
push-queue: redis-streams
push-redis-url: redis://localhost:6379/0
push-stream: iac-code:a2a:push
push-retry-key: iac-code:a2a:push:retry
push-dead-stream: iac-code:a2a:push:dead
push-consumer-group: iac-code-push
push-consumer-name: worker-1
push-lease-timeout-ms: 300000

Callback URLs 会在存储前以及分发前再次校验。默认 validator 会拒绝非 HTTP(S) URLs、localhost hostnames 和字面量 private/local IP addresses。Callback 接收方仍应执行自己的认证和幂等策略。

JSON-RPC 方法

SendMessage

运行非流式 A2A 消息轮次。响应会在轮次完成后包含一个 task 或 message。

请求

{
"jsonrpc": "2.0",
"id": "1",
"method": "SendMessage",
"params": {
"message": {
"messageId": "msg-1",
"role": "ROLE_USER",
"parts": [{"text": "Create a VPC with two vSwitches."}],
"metadata": {
"iac_code": {"cwd": "/absolute/path/to/project"}
}
},
"configuration": {
"acceptedOutputModes": ["text/plain"]
}
}
}

必需消息字段

字段类型必需描述
messageIdstring唯一客户端消息 ID
rolestring对用户输入使用 ROLE_USER
partsarray类文本、JSON 数据、原始文本、本地 file URL 或有界多模态 parts
metadata.iac_code.cwdstring建议绝对工作区路径;省略时默认为服务器进程目录

提供 metadata.iac_code.cwd 时,它必须是一个已存在的绝对目录。它必须位于允许的工作区根目录内。默认情况下,允许的根目录是服务器进程目录和系统临时目录;IACCODE_A2A_ALLOWED_CWDS 可以提供按 OS path separator 分隔的 allowlist。

支持的输入类别:

类别接受的形状限制和行为
类文本 partstext/plain、JSON、Markdown、YAML 或已配置额外 text MIME types 的 text直接追加到 prompt
JSON 数据 partsapplication/jsondata序列化为紧凑 JSON;inline 最大 1 MiB
原始文本 parts带 text-like MIME type 的 raw必须是有效 UTF-8;inline 最大 1 MiB
本地文本 file URLsfile://... 和 text-like MIME type 的 url文件必须存在于 cwd 和允许的根目录内;最大 1 MiB
多模态 raw/data/file partsimage、audio 或已配置 multimodal MIME types转换为包含 filename、media type、byte size、hash 和 source 的 prompt manifest;raw/data 最大 5 MiB,file URL 最大 25 MiB

不支持远程 HTTP(S) URL 摄取。File URL parts 必须使用本地 file:// URLs,并留在允许的工作区内。

SendStreamingMessage

运行流式 A2A 消息轮次。请求体形状与 SendMessage 相同,但服务器会以 Server-Sent Events 形式流式传输 JSON-RPC 响应。

{
"jsonrpc": "2.0",
"id": "2",
"method": "SendStreamingMessage",
"params": {
"message": {
"messageId": "msg-2",
"role": "ROLE_USER",
"parts": [{"text": "Review this ROS template."}],
"metadata": {
"iac_code": {"cwd": "/absolute/path/to/project"}
}
},
"configuration": {
"acceptedOutputModes": ["text/plain"]
}
}
}

GetTask

按 ID 返回已保存的 A2A task。使用 historyLength 可以限制返回的历史记录,且不会改变已存储的任务历史。省略它则接收服务器当前默认历史。

{
"jsonrpc": "2.0",
"id": "3",
"method": "GetTask",
"params": {
"id": "task-id",
"historyLength": 10
}
}

ListTasks

返回认证调用方可见的已知 tasks。结果按 status timestamp 降序排序,然后按 task ID 降序排序以实现稳定顺序。服务器支持 contextIdstatuspageSizepageTokenhistoryLengthincludeArtifacts

{
"jsonrpc": "2.0",
"id": "4",
"method": "ListTasks",
"params": {
"contextId": "ctx-id",
"status": "TASK_STATE_WORKING",
"pageSize": 20,
"includeArtifacts": false
}
}

当还有下一页可用时会返回 nextPageTokenincludeArtifacts 默认为 false,因此 list 响应会省略 task artifacts,除非显式请求。

CancelTask

请求取消一个运行中的 task。

{
"jsonrpc": "2.0",
"id": "5",
"method": "CancelTask",
"params": {
"id": "task-id"
}
}

如果 task 是活动的,服务器会取消正在运行的 agent 轮次并发出 canceled task state。如果 task 存在但未运行,服务器会返回标准 A2A TaskNotCancelableError

SubscribeToTask

当客户端传输支持时,订阅活动 task 更新流。

{
"jsonrpc": "2.0",
"id": "6",
"method": "SubscribeToTask",
"params": {
"id": "task-id"
}
}

对于活动 tasks,stream 会从当前 Task 开始,然后发出后续 task events,并在活动轮次完成时关闭。订阅 completed、failed、canceled 或 input-required task 会返回 task-not-found 风格错误,而不是无限等待。对于新轮次,优先使用 SendStreamingMessage;它会在一个请求中启动执行并流式传输响应。

推送通知配置方法

当服务器以 push-notifications: true 启动时,它支持:

方法用途
CreateTaskPushNotificationConfig为 task 存储 callback config
GetTaskPushNotificationConfig获取一个 callback config
ListTaskPushNotificationConfigs列出 task 的 callback configs
DeleteTaskPushNotificationConfig删除一个 callback config

创建请求示例:

{
"jsonrpc": "2.0",
"id": "7",
"method": "CreateTaskPushNotificationConfig",
"params": {
"taskId": "task-id",
"id": "webhook-1",
"url": "https://hooks.example.com/a2a",
"token": "notification-token",
"authentication": {
"scheme": "bearer",
"credentials": "callback-token"
}
}
}

当本地 push keyring 可用时,服务器会加密已存储的 notification tokens 和 callback authentication credentials。

GetExtendedAgentCard

已认证客户端可以请求扩展 Agent Card:

{
"jsonrpc": "2.0",
"id": "8",
"method": "GetExtendedAgentCard",
"params": {}
}

扩展 card 包含 public card 以及已认证运行时细节。

Task 和 Context 行为

iac-code 将 A2A contexts 映射到内部 agent runtimes:

概念行为
省略 contextIdSDK/server 生成新的 context ID
相同 contextId复用同一内部 iac-code session 和 conversation state
相同 contextId,不同 cwd作为不同工作区被拒绝
相同 contextId,并发消息Task is already working. 拒绝
不同 contextId可以并发执行
空闲 context在配置的 idle timeout 后从内存中逐出

Task 和 context IDs 必须非空,最多 128 个字符,并且只能包含字母、数字、_.:-

Task 状态

状态含义
TASK_STATE_SUBMITTEDtask 已被接受
TASK_STATE_WORKINGiac-code 正在运行 agent 轮次
TASK_STATE_INPUT_REQUIRED轮次已完成,agent 已准备好接收后续输入
TASK_STATE_CANCELED已请求并应用取消
TASK_STATE_FAILEDtask 验证或执行失败

iac-code 使用 TASK_STATE_INPUT_REQUIRED 作为正常完成状态,因为 context 仍可用于后续消息。

流式更新

执行期间,iac-code 会发出 TaskStatusUpdateEvent 更新。

Assistant text 作为 status message 投递:

{
"statusUpdate": {
"taskId": "task-1",
"contextId": "ctx-1",
"status": {
"state": "TASK_STATE_WORKING",
"message": {
"role": "ROLE_AGENT",
"parts": [{"text": "Here is the ROS template..."}]
}
}
}
}

工具和用量细节通过 metadata.iac_code 投递:

元数据路径描述
iac_code.tool.statusstartedinput_deltainput_completecompletedfailed
iac_code.tool.toolUseId用于关联工具事件的稳定 tool-use ID
iac_code.tool.name可用时的工具名称
iac_code.tool.input已完成工具输入,每个字段截断为 4000 个字符
iac_code.tool.result工具结果,每个字段截断为 4000 个字符
iac_code.permission.autoApprovedA2A server 模式拒绝工具权限请求时为 false
iac_code.thinking.typethinking-exposure 中启用 raw-thinking 时为 raw_thinking
iac_code.thinking.text原始 provider 推理 chunk,截断为 4000 个字符,仅在受信任配置启用 raw-thinking 时发出
iac_code.usage.inputTokens该轮次的 input token 数
iac_code.usage.outputTokens该轮次的 output token 数
iac_code.usage.totalTokens该轮次的 total token 数

当工具结果包含受支持的文本 artifact payload 时,服务器会在本地存储该 payload,发出标准 TaskArtifactUpdateEvent,并在 task artifacts 字段中记录该 artifact。Artifact part 使用 file:// URL 以及 mediaTypebyteSizesha256 等元数据;原始 artifact 内容不会在工具元数据中重复。

扩展

Agent Card 会公布可选的 iac-code artifact 元数据扩展:

urn:iac-code:a2a:artifact-metadata:v1

该扩展标识 metadata.iac_code 命名空间,该命名空间用于工具进度、权限决策、token 用量和本地 artifact 元数据。如果服务器配置了任何必需扩展,客户端必须在 A2A-Extensions header 中包含其 URI。缺少必需扩展会返回标准 A2A ExtensionSupportRequiredError

thinking-exposure 启用一种或多种信号类型时,Agent Card 还会公布:

urn:iac-code:a2a:thinking-exposure:v1

扩展 params 包含 enabledTypes,例如 ["tool_trace", "raw_thinking"]。这是 iac-code 元数据扩展,不是 A2A 核心流式事件类型。

错误处理

场景结果
空文本输入TASK_STATE_FAILED,消息为 A2A server currently accepts text input only.
不支持的 media type验证错误或标准 A2A content-type 错误,取决于 SDK 在何处拒绝请求
远程 URL part验证错误,因为 URL parts 必须使用本地 file:// URLs
允许工作区之外的 File URL验证错误
缺少必需的 A2A 扩展标准 A2A ExtensionSupportRequiredError
无效的工作区元数据TASK_STATE_FAILED,带 invalid workspace 消息
缺少认证或认证无效HTTP 401,响应 {"error":"Unauthorized"}
缺少 A2A server 依赖CLI 退出,并提示安装 a2a extra
缺少 provider 凭据已清理的认证错误
意外运行时错误已清理的内部错误

服务器会避免在意外错误消息中返回本地路径、secrets 和 provider 细节。