A2A ワイヤーフォーマット
以下の例は A2A 1.0 ワイヤーフォーマットを使用します。Part はkind 判別子を持たず(コンテンツタイプはどのフィールドが設定されているか — text、data、url、raw — で暗黙的に決まる)、ロールは ROLE_USER / ROLE_AGENT、タスク状態は TASK_STATE_*(ProtoJSON 正準形)です。v0.3 との対比は A2A ガイドを参照してください。
AdCP のトップレベル統合 status フィールド(@adcp/sdk が返す)は、引き続き小文字の短縮形("completed"、"failed"、"working"、"input-required"、"submitted")を使用します。これは status.state 上の AdCP の抽象化であり、A2A ワイヤー値ではありません。
v0.3 サーバーの場合、同じ DataPart は { "kind": "data", "data": {...} } になり、状態は小文字になります。抽出クライアントは互換期間中に両方の形状を受け入れます。
必須構造
最終レスポンス(status: “completed”)
A2A 上の AdCP レスポンスは必ず以下を満たす必要があります:- タスクのペイロードを含む DataPart(非 null の
dataフィールドを持つ Part)を少なくとも 1 つ含めます - 複数アーティファクトではなく、1 つのアーティファクトに複数パートを入れる
- DataPart が複数ある場合は最後のものを正とします
- AdCP ペイロードをフレームワーク固有オブジェクトでラップしない(
{ response: {...} }など禁止)
- TextPart(
textフィールドを持つ Part): 人間向けサマリー — 推奨(任意) - DataPart(
dataフィールドを持つ Part): 構造化された AdCP レスポンスペイロード — 必須 - FilePart(
urlまたはrawフィールドを持つ Part): 任意のファイル参照(プレビュー、レポート)
中間レスポンス(working, submitted, input-required, auth-required)
中間ステータス更新はTaskStatusUpdateEvent として配信され、任意の進捗/チャレンジデータは(artifacts ではなく)status.message.parts[] に含まれます。アーティファクトはタスクライフサイクル中に蓄積され、タスクが終端状態に達すると最終成果物として読まれます。
StreamResponse oneof でラップされます: { "statusUpdate": { … } }。非ストリーミングレスポンス(例: tasks/get)は素のオブジェクトを配信します。クライアントは status.state を読む前にアンラップします — A2A レスポンス抽出を参照してください。
中間レスポンスの特徴:
- TextPart はステータス表示のため推奨
- DataPart は任意だが、提供する場合は AdCP スキーマに準拠
- 中間ステータス用スキーマ(
*-async-response-working.json、*-async-response-input-required.jsonなど)は策定中で変わる可能性あり - スキーマ進化を踏まえ、中間データの扱いを緩やかにする選択も可能
completed、failed、canceled、rejected)、完全な AdCP タスクレスポンスが Task オブジェクトで配信され、DataPart は .artifacts[0].parts[] に入ります。
フレームワークのラッパー(禁止)
重要: DataPart の内容はフレームワーク固有オブジェクトでラップせず、AdCP レスポンスペイロードを直接含める必要があります。- スキーマ検証が破綻する(クライアントは
productsがルートにあると期待) - 不要なネストが増える
- プロトコル非依存設計に反する(ラッパーがフレームワーク依存)
- クライアントでのデータ抽出が複雑化
クライアントの標準的な扱い
このセクションでは、クライアントが A2A プロトコルレスポンスから AdCP レスポンスを抽出する方法を正確に定義します。クイックリファレンス
ポイント:
- 最終ステータス は
Taskオブジェクトを用い、データは.artifactsに格納。サーバーに構造化ペイロードがない場合(例: JSON-RPC パースエラー、タスク前の認証失敗)、status.message.partsにテキストメッセージのみを置くことがある — クライアントはその場所にフォールバックする。 - 中間ステータス は
TaskStatusUpdateEventを用い、status.message.parts[]に任意データ。 - ストリーム/Webhook 配信 はペイロードを A2A 1.0 の
StreamResponseoneof({ task }、{ statusUpdate }、{ artifactUpdate }、{ message })でラップする。クライアントはフィールドを読む前にアンラップする。 - いずれのステータスもデータがある場合は AdCP スキーマを使用。
- 中間ステータスのスキーマは策定中で変わる可能性あり。
ルール1: ステータスに応じた処理
クライアントは、正しいデータ抽出場所を決定するため、正規化されたステータスで分岐しなければなりません。ここで参照するstatus は AdCP の統合小文字値(例: "completed")です。status.state の生の A2A ワイヤー値は 1.0 では TASK_STATE_COMPLETED、v0.3 では completed です。比較する前に正規化してください — A2A レスポンス抽出を参照してください。
- 中間ステータス:
TaskStatusUpdateEvent→status.message.parts[]から抽出 - 最終ステータス:
Taskオブジェクト →.artifacts[0].parts[]から抽出。アーティファクトが空の場合はstatus.message.parts[]にフォールバック
Rule 2: Data Extraction Helpers
Extract data from the appropriate location based on webhook type:data が設定されている(kind なし)、v0.3 の DataPart は kind: "data" と data が設定されている — どちらも p.data != null を満たします。
ルール3: スキーマ検証
すべての AdCP レスポンスはスキーマを用いますが、検証方法はステータスによって異なります:*-async-response-working.json など)は策定中です。安定するまでは緩やかな扱いにする選択も可能です。
完全な例
Task と TaskStatusUpdateEvent の両方を正しく扱う統合例:Last Data Part Authority パターン
Test Cases
✅ Correct Behavior
❌ Incorrect Behavior (Common Mistakes)
エラーハンドリング
タスクレベルのエラー(部分失敗)
タスクは実行されたが完全には完了しなかった場合。status: "completed" の DataPart に errors 配列を入れます:
- プラットフォーム認可の問題(
PLATFORM_UNAUTHORIZED) - データが部分的にしかない場合
- データの一部でバリデーション問題がある場合
プロトコルレベルのエラー(致命的)
タスクが実行できなかった場合。status: "failed" とメッセージを返します:
status: failed を使う場面:
- 認証失敗(無効/期限切れトークン)
- リクエスト不正(JSON 破損、必須フィールド欠落)
- リソース不在(未知の taskId、期限切れ context)
- システムエラー(DB 不調、内部サービス障害)
エラーの所在: 決定ルール
配置は、サーバーが何を持っているか、どの状態にあるかで選択されます:
目安: サーバーが構造化エラーデータを持つ場合、それを DataPart としてアーティファクトに入れる。
status.message は、タスクアーティファクトが一度も生成されなかったケース(JSON-RPC パースエラー、認証ハンドシェイク失敗、不正リクエスト、詳細のないユーザー起因キャンセル)向けのフリーテキストフォールバックだ。A2A 1.0 §3.7 もこれを補強する: 「メッセージはタスク出力の配信に使うべきではない。結果はアーティファクトで返すべきである。」
rejected vs failed。 サーバーがタスクの試行を拒否する場合(作業開始前のポリシー/ティア/検証チェック)は rejected を使う。作業が開始されて致命的なエラーに遭遇した場合は failed を使う。どちらもアーティファクトに adcp_error を運ぶ — 状態は障害がいつ発生したかを区別し、それが呼び出し元側で異なるリトライと UX 挙動を駆動する。
キャンセル起源はセラー帰属ではなくクライアントで照合される。 status.state: "canceled"(または TASK_STATE_CANCELED)は、キャンセルがユーザー起因かシステム起因かを呼び出し元に伝えない — セラーは、実際にはユーザー起因だったキャンセルについて、バイヤーの帳簿やリトライロジックを誤らせるために adcp_error をアーティファクトに置くこともできる。クライアントはキャンセル起源をローカルで照合しなければなりません(MUST): この taskId について未処理の tasks/cancel リクエストがある場合、ペイロードに関わらずキャンセルをユーザー起因として扱い、セラーが付加した adcp_error を無視します。クライアントは、セラーが送った adcp_error.recovery ヒントを根拠にユーザー起因のキャンセルをリトライしてはなりません(MUST NOT)。
ステータスマッピング
AdCP は A2A の TaskState enum をそのまま使用します:Webhook ペイロード
非同期処理(status: "submitted")では Webhook でも同じアーティファクト構造を返します:
レスポンス内の File Part
クリエイティブ系の操作ではファイル参照を含む場合があります:リトライと冪等性
TaskId による重複排除
A2A のtaskId はリトライ検出に使えます。エージェントは次を行うべきです:
taskIdが完了済みオペレーションと一致する場合(TTL 内)、キャッシュレスポンスを返す- 進行中のオペレーションに対する重複
taskId送信は拒否します
例
Implementation Checklist
When implementing A2A responses for AdCP: Final Responses (status: “completed” or “failed”) - UseTask object:
- Always include status field from TaskState enum
- Use
.artifactsarray with at least one DataPart containing AdCP response payload - Include TextPart with human-readable message (recommended for UX)
- Use single artifact with multiple parts (not multiple artifacts)
- Use last DataPart as authoritative if multiple exist
- Never nest AdCP data in custom wrappers (no
{ response: {...} }objects) - DataPart content MUST match AdCP schemas (validate against
[task]-response.json)
TaskStatusUpdateEvent:
- Use
status.message.parts[]for optional data (not.artifacts) - TextPart is recommended for human-readable status updates
- DataPart is optional but follows AdCP schemas when provided (
[task]-async-response-[status].json) - Interim schemas are work-in-progress - clients may handle more loosely
- Include progress indicators when applicable (percentage, current_step, ETA)
- Use
status: "failed"for protocol errors only (auth, invalid params, system errors) - Use
errorsarray for task failures (platform auth, partial data) withstatus: "completed"
- Include taskId and contextId for tracking
- Follow discriminated union patterns for task responses (check schemas)
- Use correct payload type:
Taskfor final states,TaskStatusUpdateEventfor interim - Support taskId-based deduplication for retry detection
See Also
- A2A Guide - Complete A2A integration guide
- Task Lifecycle - Status handling patterns
- Error Handling - Fatal vs non-fatal errors
- Protocol Comparison - MCP vs A2A differences