Slack MCP Agent — Slack UI カード仕様書¶
v1.2 / 2026-04-20
Block Kit JSON レベルの詳細仕様。
docs/mvp-spec.mdSection 7 の実装ガイドとして使用する。
1. 設計原則¶
| # | 原則 | 詳細 |
|---|---|---|
| P-1 | 1 タスク 4 メッセージ | Task / Prompt / Process / Execution の 4 つだけ投稿 |
| P-2 | chat.update で書き換え | 状態遷移ごとにブロック全体を再構築して chat.update。スレッド肥大化防止 |
| P-3 | rich_text 禁止 | rich_text ブロックは ~13,200 文字制限 + section への置換不可。使わない |
| P-4 | テキスト truncation | section の mrkdwn は最大 3000 文字。超過時は末尾 ... で切り詰め |
| P-5 | ブロック上限 | 1 メッセージ最大 50 ブロック。実際は最大 ~10 ブロックで収まる |
| P-6 | actions 要素上限 | 1 actions ブロック最大 25 要素。実際は最大 3 ボタン |
| P-7 | 使用ブロック | header / section / divider / context / actions のみ |
| P-8 | attachment color で状態色 | attachments[].color で左端カラーバーを表示し、カード状態を色で識別可能にする |
| P-9 | card ブロック不使用 | card ブロックは body 200 文字制限のため不採用。section ベースで構成する |
2. 共通コンポーネント¶
2.1 テキスト truncation¶
_MRKDWN_MAX = 3000
def _truncate(text: str, limit: int = _MRKDWN_MAX) -> str:
if len(text) <= limit:
return text
return text[:limit - 3] + "..."
2.2 Priority 絵文字マッピング¶
| priority | emoji | 表示 |
|---|---|---|
low |
🟢 | Low |
medium |
🟡 | Medium |
high |
🔴 | High |
2.3 ステップ進捗の絵文字¶
| 状態 | emoji | 意味 |
|---|---|---|
| 未実行 | ⬜ | 待機中 |
| 実行中 | 🔄 | 処理中 |
| 完了 | ✅ | 成功 |
| 失敗 | ❌ | エラー |
2.4 状態カラーマッピング(attachment color)¶
Block Kit にはカスタム背景色の概念がないが、attachments[].color パラメータで左端にカラーバーを表示できる。ブロックを attachments[].blocks に入れることで、状態を色で視覚的に識別可能にする。
| 状態 | color | Hex | 用途 |
|---|---|---|---|
| 生成中 | 黄 | #f2c744 |
L1-L3 処理中 |
| 承認待ち | 青 | #2196f3 |
ユーザーアクション要求 |
| 承認済み | 緑 | #36a64f |
承認完了 |
| 却下 / 失敗 | 赤 | #e01e5a |
エラー・却下 |
| 実行中 | 紺 | #1264a3 |
Agent 処理中 |
| 完了 | 緑 | #36a64f |
正常完了 |
| 中止 | グレー | #888888 |
キャンセル |
attachment 構造テンプレート¶
ブロックをトップレベルの blocks ではなく attachments[].blocks に入れることで、色付きカードとして表示する。
STATUS_COLORS = {
"generating": "#f2c744",
"pending_approval": "#2196f3",
"approved": "#36a64f",
"rejected": "#e01e5a",
"running": "#1264a3",
"completed": "#36a64f",
"failed": "#e01e5a",
"cancelled": "#888888",
}
def wrap_in_attachment(blocks: list[dict], status: str) -> dict:
"""ブロック配列を色付き attachment でラップする。"""
return {
"attachments": [
{
"color": STATUS_COLORS.get(status, "#888888"),
"blocks": blocks,
}
]
}
chat.postMessage / chat.update 時の使い方¶
# 投稿時
result = await client.chat_postMessage(
channel=channel,
thread_ts=thread_ts,
text="実行方針を生成中...", # fallback
**wrap_in_attachment(
blocks=build_prompt_card_generating(),
status="generating",
),
)
# 更新時
await client.chat_update(
channel=channel,
ts=message_ts,
text="実行方針の確認をお願いします", # fallback
**wrap_in_attachment(
blocks=build_prompt_card_pending(prompt_content, task_id, prompt_id, version),
status="pending_approval",
),
)
注意:
attachments使用時はトップレベルのblocksパラメータではなくattachments[].blocksにブロックを渡す。両方指定するとブロックが二重表示される。
section.fields による 2 列レイアウト¶
メタデータ表示(承認者・時刻等)は section.fields で 2 列キーバリュー配置にすると見やすくなる。
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*承認者*\n<@U12345>" },
{ "type": "mrkdwn", "text": "*時刻*\n14:33:12" },
{ "type": "mrkdwn", "text": "*バージョン*\nv1" },
{ "type": "mrkdwn", "text": "*タスクID*\n`01JSGX...`" }
]
}
制約: fields は最大 10 項目、各項目最大 2000 文字。
2.5 Action ID 一覧¶
| action_id | 用途 | value |
|---|---|---|
approve_prompt |
Prompt 承認 | prompt_id |
reject_prompt |
Prompt 却下 → モーダル表示 | prompt_id |
approve_process |
Process 承認 | process_id |
reject_process |
Process 却下 → モーダル表示 | process_id |
cancel_execution |
実行中止 | execution_id |
retry_execution |
失敗時再実行 | execution_id |
3. Card #1: Task カード¶
3.1 状態: generating¶
投稿直後。L1 で Task を分析中。color: #f2c744(黄)
{
"attachments": [{
"color": "#f2c744",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "受け付けました。タスクを分析中..."
}
}
]
}]
}
関数: build_task_card_generating()
3.2 状態: complete¶
L1 完了。Task 情報で更新。color: #36a64f(緑)
{
"attachments": [{
"color": "#36a64f",
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "{title}", "emoji": true }
},
{ "type": "divider" },
{
"type": "section",
"text": { "type": "mrkdwn", "text": "*説明*\n{description}" }
},
{
"type": "section",
"fields": [
{ "type": "mrkdwn", "text": "*優先度*\n{priority_emoji} {priority_label}" },
{ "type": "mrkdwn", "text": "*種別*\n{task_type}" }
]
},
{ "type": "divider" },
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "*タスクID:* `{task_id}`" }
]
}
]
}]
}
関数: build_task_card_complete(title, description, priority, task_type, task_id)
4. Card #2: Prompt カード¶
4.1 状態: generating¶
L2 で方針を生成中。
[
{
"type": "header",
"text": { "type": "plain_text", "text": "📝 実行方針", "emoji": true }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "実行方針を生成中..." }
}
]
関数: build_prompt_card_generating()
4.2 状態: pending_approval¶
承認待ち。承認 / 却下ボタンを表示。color: #2196f3(青)
{
"attachments": [{
"color": "#2196f3",
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "📝 実行方針", "emoji": true }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "{prompt_content (truncated)}" }
},
{ "type": "divider" },
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "✅ 承認", "emoji": true },
"action_id": "approve_prompt",
"value": "{prompt_id}",
"style": "primary"
},
{
"type": "button",
"text": { "type": "plain_text", "text": "❌ 却下", "emoji": true },
"action_id": "reject_prompt",
"value": "{prompt_id}",
"style": "danger"
}
]
},
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "*タスクID:* `{task_id}` · *バージョン:* v{version}" }
]
}
]
}]
}
関数: build_prompt_card_pending(prompt_content, task_id, prompt_id, version)
4.3 状態: approved¶
[
{
"type": "header",
"text": { "type": "plain_text", "text": "📝 実行方針(承認済み)", "emoji": true }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "{prompt_content (truncated)}" }
},
{ "type": "divider" },
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "✅ 承認: <@{approved_by}> · {approved_at}" }
]
}
]
関数: build_prompt_card_approved(prompt_content, approved_by, approved_at)
4.4 状態: rejected (→ 再生成あり)¶
却下されたカード。再生成版がある場合は「再生成済み」と表示。
[
{
"type": "header",
"text": { "type": "plain_text", "text": "📝 実行方針(却下 → 再生成済み)", "emoji": true }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "{prompt_content (truncated)}" }
},
{ "type": "divider" },
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "❌ 却下: <@{rejected_by}> · 理由: {rejection_reason}" },
{ "type": "mrkdwn", "text": "➡️ 新しいバージョン v{next_version} が生成されました" }
]
}
]
関数: build_prompt_card_rejected(prompt_content, rejected_by, rejection_reason, next_version)
4.5 状態: rejected (→ 再生成なし、タスクキャンセル)¶
将来: 再生成上限に達した場合などのフォールバック。
[
{
"type": "header",
"text": { "type": "plain_text", "text": "📝 実行方針(キャンセル)", "emoji": true }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "タスクをキャンセルしました" }
}
]
5. Card #3: Process カード¶
5.1 状態: generating¶
[
{
"type": "header",
"text": { "type": "plain_text", "text": "⚙️ 実行ステップ", "emoji": true }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "実行ステップを生成中..." }
}
]
関数: build_process_card_generating()
5.2 状態: pending_approval¶
[
{
"type": "header",
"text": { "type": "plain_text", "text": "⚙️ 実行ステップ", "emoji": true }
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "1. *従業員一覧を取得* — `list_employees`\n2. *勤怠データ取得* — `list_attendance`\n3. *残業時間計算* — `calculate_overtime`\n4. *Sheet 書き込み* — `write_rows_to_google_sheet`\n5. *完了通知* — `send_slack_dm`"
}
},
{ "type": "divider" },
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "✅ 承認", "emoji": true },
"action_id": "approve_process",
"value": "{process_id}",
"style": "primary"
},
{
"type": "button",
"text": { "type": "plain_text", "text": "❌ 却下", "emoji": true },
"action_id": "reject_process",
"value": "{process_id}",
"style": "danger"
}
]
},
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "*タスクID:* `{task_id}` · *バージョン:* v{version}" }
]
}
]
ステップテキスト生成関数: _format_steps_text(steps)
def _format_steps_text(steps: list[dict]) -> str:
lines: list[str] = []
for s in steps:
order = s.get("order", "?")
title = s.get("title", "")
tool = s.get("tool", "")
human = " 🔍" if s.get("requiresHumanCheck") else ""
lines.append(f"{order}. *{title}* — `{tool}`{human}")
return "\n".join(lines)
関数: build_process_card_pending(steps, task_id, process_id, version)
5.3 状態: approved¶
[
{
"type": "header",
"text": { "type": "plain_text", "text": "⚙️ 実行ステップ(承認済み)", "emoji": true }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "{steps_text}" }
},
{ "type": "divider" },
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "✅ 承認: <@{approved_by}> · {approved_at}" }
]
}
]
関数: build_process_card_approved(steps, approved_by, approved_at)
5.4 状態: rejected (→ 再生成あり)¶
Prompt カードの rejected と同じパターン。
[
{
"type": "header",
"text": { "type": "plain_text", "text": "⚙️ 実行ステップ(却下 → 再生成済み)", "emoji": true }
},
{
"type": "section",
"text": { "type": "mrkdwn", "text": "{steps_text}" }
},
{ "type": "divider" },
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "❌ 却下: <@{rejected_by}> · 理由: {rejection_reason}" },
{ "type": "mrkdwn", "text": "➡️ 新しいバージョン v{next_version} が生成されました" }
]
}
]
関数: build_process_card_rejected(steps, rejected_by, rejection_reason, next_version)
6. Card #4: Execution カード¶
6.1 状態: running¶
進捗更新ごとに chat.update。[中止] ボタンを常時表示。color: #1264a3(紺)
MVP 実装では、Execution カードの更新タイミングは L4 セッション開始時と完了・失敗・中止時に限定される。ツール呼び出しごとの逐次更新(
on_progress経由のchat.update)は Post-MVP(docs/post-mvp-roadmap.md§4.8)。下記ブロックはサンプルだが、MVP ではcompleted_tools/current_toolがすべて空の状態で表示される。
{
"attachments": [{
"color": "#1264a3",
"blocks": [
{
"type": "header",
"text": { "type": "plain_text", "text": "🚀 実行中", "emoji": true }
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "✅ 1. *従業員一覧を取得* — `list_employees`\n🔄 2. *勤怠データ取得* — `list_attendance` 実行中...\n⬜ 3. *残業時間計算* — `calculate_overtime`\n⬜ 4. *Sheet 書き込み* — `write_rows_to_google_sheet`\n⬜ 5. *完了通知* — `send_slack_dm`"
}
},
{ "type": "divider" },
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "進捗: 1/5 完了" }
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "⏹️ 中止", "emoji": true },
"action_id": "cancel_execution",
"value": "{execution_id}",
"style": "danger",
"confirm": {
"title": { "type": "plain_text", "text": "実行を中止しますか?" },
"text": { "type": "plain_text", "text": "中止すると元に戻せません。新しいタスクとして再依頼が必要です。" },
"confirm": { "type": "plain_text", "text": "中止する" },
"deny": { "type": "plain_text", "text": "キャンセル" }
}
}
]
}
]
}]
}
ステップ進捗テキスト生成関数: _build_step_lines(steps, completed_tools, current_tool)
def _build_step_lines(
steps: list[dict],
completed_tools: list[str] | None = None,
current_tool: str | None = None,
failed_tool: str | None = None,
) -> str:
completed = set(completed_tools or [])
lines: list[str] = []
for s in steps:
tool = s.get("tool", "")
title = s.get("title", "")
order = s.get("order", "?")
if tool == failed_tool:
lines.append(f"❌ {order}. *{title}* — `{tool}`")
elif tool == current_tool:
lines.append(f"🔄 {order}. *{title}* — `{tool}` 実行中...")
elif tool in completed:
lines.append(f"✅ {order}. *{title}* — `{tool}`")
else:
lines.append(f"⬜ {order}. *{title}* — `{tool}`")
return "\n".join(lines)
関数: build_execution_card_running(steps, current_tool, completed_tools, execution_id)
6.2 状態: completed¶
[
{
"type": "header",
"text": { "type": "plain_text", "text": "✅ 実行完了", "emoji": true }
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "✅ 1. *従業員一覧を取得* — `list_employees`\n✅ 2. *勤怠データ取得* — `list_attendance`\n✅ 3. *残業時間計算* — `calculate_overtime`\n✅ 4. *Sheet 書き込み* — `write_rows_to_google_sheet`\n✅ 5. *完了通知* — `send_slack_dm`"
}
},
{ "type": "divider" },
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*サマリー*\n{summary}"
}
},
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "⏱️ 実行時間: {elapsed}秒 · 完了: {completed_at}" }
]
}
]
関数: build_execution_card_completed(steps, completed_tools, summary, elapsed, completed_at)
6.3 状態: failed¶
[再実行] ボタンを表示。
[
{
"type": "header",
"text": { "type": "plain_text", "text": "❌ 実行失敗", "emoji": true }
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "✅ 1. *従業員一覧を取得* — `list_employees`\n✅ 2. *勤怠データ取得* — `list_attendance`\n❌ 3. *残業時間計算* — `calculate_overtime`\n⬜ 4. *Sheet 書き込み* — `write_rows_to_google_sheet`\n⬜ 5. *完了通知* — `send_slack_dm`"
}
},
{ "type": "divider" },
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*エラー*\n{error_message}"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": { "type": "plain_text", "text": "🔄 再実行", "emoji": true },
"action_id": "retry_execution",
"value": "{execution_id}",
"style": "primary"
}
]
},
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "⏱️ 実行時間: {elapsed}秒 · 失敗: {failed_at}" }
]
}
]
関数: build_execution_card_failed(steps, completed_tools, failed_tool, error, execution_id, elapsed, failed_at)
6.4 状態: cancelled¶
[
{
"type": "header",
"text": { "type": "plain_text", "text": "⏹️ 実行中止", "emoji": true }
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "✅ 1. *従業員一覧を取得* — `list_employees`\n✅ 2. *勤怠データ取得* — `list_attendance`\n⬜ 3. *残業時間計算* — `calculate_overtime`\n⬜ 4. *Sheet 書き込み* — `write_rows_to_google_sheet`\n⬜ 5. *完了通知* — `send_slack_dm`"
}
},
{ "type": "divider" },
{
"type": "context",
"elements": [
{ "type": "mrkdwn", "text": "⏹️ <@{cancelled_by}> により中止されました · {cancelled_at}" }
]
}
]
関数: build_execution_card_cancelled(steps, completed_tools, cancelled_by, cancelled_at)
7. 却下理由モーダル¶
Prompt / Process の [却下] ボタン押下時に views.open で表示するモーダル。
7.1 モーダル定義¶
{
"type": "modal",
"callback_id": "rejection_reason_modal",
"title": {
"type": "plain_text",
"text": "却下理由"
},
"submit": {
"type": "plain_text",
"text": "送信して再生成"
},
"close": {
"type": "plain_text",
"text": "キャンセル"
},
"private_metadata": "{\"type\": \"prompt|process\", \"id\": \"{resource_id}\", \"task_id\": \"{task_id}\"}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "却下理由を入力してください。この内容を反映して新しいバージョンを生成します。"
}
},
{
"type": "input",
"block_id": "rejection_reason_block",
"element": {
"type": "plain_text_input",
"action_id": "rejection_reason_input",
"multiline": true,
"placeholder": {
"type": "plain_text",
"text": "例: ステップ 3 の前にデータの検証を追加してください"
}
},
"label": {
"type": "plain_text",
"text": "却下理由"
}
}
]
}
7.2 モーダル処理フロー¶
- [却下] ボタン押下 →
trigger_idを受け取る views.open(trigger_id, view)でモーダル表示- ユーザーが理由を入力して [送信して再生成] を押下
view_submissionイベントでcallback_id: rejection_reason_modalを受信private_metadataからtypeとidを取得rejection_reasonを DB に保存- 既存カードを「却下 → 再生成済み」状態に
chat.update - 新しいバージョンの Prompt/Process を生成
- 新しいカードを投稿
7.3 View Submission ハンドラ¶
@app.view("rejection_reason_modal")
def handle_rejection_modal(ack, view, client):
ack()
metadata = json.loads(view["private_metadata"])
reason = view["state"]["values"]["rejection_reason_block"]["rejection_reason_input"]["value"]
resource_type = metadata["type"] # "prompt" or "process"
resource_id = metadata["id"]
task_id = metadata["task_id"]
# → 再生成フローを開始
8. Agent Container サジェストプロンプト(Post-MVP)¶
MVP では Agent Container を実装しない。本節は Post-MVP 実装時のサジェストプロンプト仕様メモ。Agent Container 自体の詳細は
docs/post-mvp-roadmap.md§4.6 を参照。
Agent Container を開いた時に表示するサジェストプロンプト。
suggested_prompts = [
{
"title": "勤怠集計",
"message": "今月の勤怠をまとめて"
},
{
"title": "残業確認",
"message": "先月の残業時間を確認して"
},
{
"title": "従業員一覧",
"message": "従業員一覧を取得して"
}
]
8.1 threadStarted ハンドラ¶
async def thread_started(say, set_suggested_prompts):
await say(text="HR AI Agent です。業務を依頼してください。")
await set_suggested_prompts(prompts=suggested_prompts)
9. Slack API 呼び出しパターン¶
9.1 カード投稿 → ts 取得¶
blocks = build_prompt_card_generating()
payload = wrap_in_attachment(blocks, "generating")
result = await client.chat_postMessage(
channel=channel,
thread_ts=thread_ts,
text="実行方針を生成中...", # fallback
**payload,
)
message_ts = result["ts"]
# → slack_messages テーブルに保存
9.2 カード更新¶
blocks = build_prompt_card_pending(prompt_content, task_id, prompt_id, version)
payload = wrap_in_attachment(blocks, "pending_approval")
await client.chat_update(
channel=channel,
ts=message_ts, # slack_messages から取得
text="実行方針の確認をお願いします", # fallback
**payload,
)
9.3 モーダル表示¶
await client.views_open(
trigger_id=body["trigger_id"],
view=build_rejection_modal(resource_type, resource_id, task_id),
)
9.4 Rate Limit¶
| API | Tier | Rate |
|---|---|---|
chat.postMessage |
Tier 4 | 100+/min |
chat.update |
Tier 3 | 50+/min |
views.open |
Tier 4 | 100+/min |
views.publish |
Tier 4 | 100+/min |
L4 実行中の進捗更新は POLL_INTERVAL_SECONDS=3(20 回/min)で Tier 3 の制限内。
10. 関数一覧¶
| 関数名 | 引数 | 返り値 | 用途 |
|---|---|---|---|
build_task_card_generating() |
なし | list[dict] |
Task 分析中 |
build_task_card_complete(title, description, priority, task_type, task_id) |
5 | list[dict] |
Task 分析完了 |
build_prompt_card_generating() |
なし | list[dict] |
Prompt 生成中 |
build_prompt_card_pending(prompt_content, task_id, prompt_id, version) |
4 | list[dict] |
Prompt 承認待ち |
build_prompt_card_approved(prompt_content, approved_by, approved_at) |
3 | list[dict] |
Prompt 承認済み |
build_prompt_card_rejected(prompt_content, rejected_by, rejection_reason, next_version) |
4 | list[dict] |
Prompt 却下 → 再生成 |
build_process_card_generating() |
なし | list[dict] |
Process 生成中 |
build_process_card_pending(steps, task_id, process_id, version) |
4 | list[dict] |
Process 承認待ち |
build_process_card_approved(steps, approved_by, approved_at) |
3 | list[dict] |
Process 承認済み |
build_process_card_rejected(steps, rejected_by, rejection_reason, next_version) |
4 | list[dict] |
Process 却下 → 再生成 |
build_execution_card_running(steps, current_tool, completed_tools, execution_id) |
4 | list[dict] |
Execution 実行中 |
build_execution_card_completed(steps, completed_tools, summary, elapsed, completed_at) |
5 | list[dict] |
Execution 完了 |
build_execution_card_failed(steps, completed_tools, failed_tool, error, execution_id, elapsed, failed_at) |
7 | list[dict] |
Execution 失敗 |
build_execution_card_cancelled(steps, completed_tools, cancelled_by, cancelled_at) |
4 | list[dict] |
Execution 中止 |
build_rejection_modal(resource_type, resource_id, task_id) |
3 | dict |
却下理由モーダル |
wrap_in_attachment(blocks, status) |
2 | dict |
ブロックを色付き attachment でラップ |
11. プロトタイプからの差分¶
| 項目 | プロトタイプ (cards.py) |
本仕様 |
|---|---|---|
| Prompt 却下 | タスクキャンセルのみ | 理由モーダル → 再生成 |
| Process 却下 | タスクキャンセルのみ | 理由モーダル → 再生成 |
| Execution 中止 | なし | [中止] ボタン + 確認ダイアログ |
| Execution 再実行 | なし | [再実行] ボタン |
| バージョン表示 | なし | Prompt/Process カードに v{N} 表示 |
| 承認時刻 | なし | Context に表示 |
| 実行時間 | なし | Execution 完了/失敗カードに表示 |
| 中止ボタン確認 | - | confirm オブジェクトで誤操作防止 |
| 失敗ステップ表示 | 全て ⬜ のまま | ❌ マーク + failed_tool 識別 |
| 状態カラーバー | なし | attachment color で状態色表示(黄/青/緑/赤/紺/グレー) |
| メタデータ 2 列表示 | context のみ | section.fields で 2 列キーバリュー |
変更履歴¶
| 日付 | バージョン | 変更内容 |
|---|---|---|
| 2026-04-18 | v1.0 | 初版作成 |
| 2026-04-18 | v1.1 | attachment color による状態カラーバー、section.fields による 2 列レイアウト追加 |
| 2026-04-20 | v1.2 | Agent Container サジェストプロンプト節を Post-MVP スコープに移動(MVP はチャンネルメンションのみ) |