Documentation Index
Fetch the complete documentation index at: https://adcp-docs-ja.pier1.co.jp/llms.txt
Use this file to discover all available pages before exploring further.
すべての AdCP レスポンスには status フィールドが含まれ、現在の状態と次に取るべき行動を示します。これはすべての AdCP 処理の基盤です。
ステータス値
AdCP は A2A プロトコルの TaskState enum と同じステータス値を使用します:
| Status | Meaning | Your Action |
|---|
submitted | Task queued for execution | Show “queued” indicator, wait for updates |
working | Agent actively processing | Show progress, poll frequently for updates |
input-required | Needs information from you | Read message field, prompt user, send follow-up |
completed | Successfully finished | Process data, show success message |
canceled | User/system canceled task | Show cancellation notice, clean up |
failed | Error occurred | Show error from message, handle gracefully |
rejected | Agent rejected the request | Show rejection reason, don’t retry |
auth-required | Authentication needed | Prompt for auth, retry with credentials |
unknown | Indeterminate state | Log for debugging, may need manual intervention |
レスポンス構造
AdCP レスポンスはタスク固有フィールドがトップレベルにある フラット構造 です:
{
"status": "completed", // Always present: what state we're in
"message": "Found 5 products", // Always present: human explanation
"context_id": "ctx-123", // Session continuity
"context": { // Application-level context echoed back
"ui": "buyer_dashboard"
},
"products": [...] // Task-specific fields at top level
}
ステータス処理
基本パターン
function handleAdcpResponse(response) {
switch (response.status) {
case 'completed':
// 成功 - データ処理(タスクフィールドはトップレベル)
showSuccess(response.message);
return processData(response);
case 'input-required':
// 追加情報が必要 - ユーザーに確認
const userInput = await promptUser(response.message);
return sendFollowUp(response.context_id, userInput);
case 'working':
// 進行中 - 進捗表示して待機
showProgress(response.message);
return pollForUpdates(response.context_id);
case 'failed':
// エラー - メッセージを表示し丁寧に処理
showError(response.message);
return handleError(response.errors);
case 'auth-required':
// 認証が必要
const credentials = await getAuth();
return retryWithAuth(credentials);
default:
// 想定外のステータス
console.warn('Unknown status:', response.status);
showMessage(response.message);
}
}
確認フロー
ステータスが input-required のとき、必要な情報が message で示されます:
{
"status": "input-required",
"message": "I need more information about your campaign. What's your budget and target audience?",
"context_id": "ctx-123",
"products": [],
"suggestions": ["budget", "audience", "timing"]
}
クライアントサイドの処理:
if (response.status === 'input-required') {
// message から必要項目を抽出
const missingInfo = extractRequirements(response.message);
// 必要項目に応じて質問
const answers = await promptForInfo(missingInfo);
// 同じ context_id で追送
return sendMessage(response.context_id, answers);
}
承認フロー
人による承認は input-required の特殊ケースです:
{
"status": "input-required",
"message": "Media buy exceeds auto-approval limit ($100K). Please approve to proceed with campaign creation.",
"context_id": "ctx-123",
"approval_required": true,
"amount": 150000,
"reason": "exceeds_limit"
}
クライアントサイドの処理:
if (response.status === 'input-required' && response.approval_required) {
// 承認 UI を表示
const approved = await showApprovalDialog(response.message, response);
// 承認結果を送信
const decision = approved ? "Approved" : "Rejected";
return sendMessage(response.context_id, decision);
}
長時間オペレーション
非同期オペレーションは working または submitted で開始し、進捗を返します:
{
"status": "working",
"message": "Creating media buy. Validating inventory availability...",
"context_id": "ctx-123",
"task_id": "task-456",
"progress": 25,
"step": "inventory_validation"
}
プロトコル別のポーリング:
- MCP: context_id を使ってポーリング
- A2A: SSE ストリームでリアルタイム更新を購読
ステータスの流れ
タスクは予測可能な状態を経由して進行する:
submitted → working → completed
↓ ↓ ↑
input-required → → → → →
↓
failed
submitted: 実行待ち。Webhook を設定するかポーリング
working: 処理中。高頻度でポーリング
input-required: ユーザー入力が必要。会話を継続
completed: 成功。結果を処理
failed: エラー。適切に処理
ポーリングパターン
ステータス別ポーリング間隔
ステータスによってポーリング頻度を変えます:
const POLLING_INTERVALS = {
working: 5000, // 5 seconds - should complete within 120s
submitted: 60000, // 1 minute - long-running operations
'input-required': null // Don't poll - wait for user input
};
async function pollForUpdates(taskId, currentStatus) {
const interval = POLLING_INTERVALS[currentStatus];
if (!interval) return;
await sleep(interval);
const response = await adcp.call('tasks/get', {
task_id: taskId,
include_result: true
});
if (['completed', 'failed', 'canceled'].includes(response.status)) {
return response;
}
return pollForUpdates(taskId, response.status);
}
タイムアウト処理
オペレーション種別に応じて妥当なタイムアウトを設定します:
const TIMEOUTS = {
sync: 30_000, // 30 seconds for immediate operations
interactive: 300_000, // 5 minutes for human input
working: 120_000, // 2 minutes for working tasks
submitted: 86_400_000 // 24 hours for submitted tasks
};
function setTimeoutForStatus(status) {
switch (status) {
case 'working': return TIMEOUTS.working;
case 'submitted': return TIMEOUTS.submitted;
case 'input-required': return TIMEOUTS.interactive;
default: return TIMEOUTS.sync;
}
}
タスク再同期
tasks/list で失われた状態を復元します:
// 保留中のオペレーションを取得
const pending = await session.call('tasks/list', {
filters: {
statuses: ["submitted", "working", "input-required"]
}
});
// ローカル状態と突き合わせ
const missingTasks = pending.tasks.filter(task =>
!localState.hasTask(task.task_id)
);
// 未追跡タスクの監視を再開
for (const task of missingTasks) {
startPolling(task.task_id);
}
ベストプラクティス
- まず status を確認 - 成功前提にしません
- すべてのステータスを処理 - 未知の状態も default でカバー
- context_id を保持 - 会話継続に必須
- task_id で追跡 - 特に長時間オペレーションで重要
- タイムアウトを実装 - 無限に待たない
- ステータス遷移をログ - デバッグと監査に有用
次のステップ