kiro-discord-bot

使用 NATS 啟用 A2A #

A2A 讓一個 kiro-discord-bot runtime 可以透過 NATS 與 JetStream 把工作委派給另一個 bot runtime。這是選用功能;當 NATS_URL 為空時,A2A 會完全停用,既有 Discord bot 行為不變。

想實際開啟功能時請從本頁開始。協議實作模型與關鍵字見 A2A 協議模型。Release gates、ACL hardening 與 rollback smoke checks 見英文 A2A NATS Rollout。完整環境變數見 環境變數參考

A2A 能做什麼 #

A2A 提供 durable cross-bot task delegation:

A2A 不會取代一般 Discord 回覆。只有在 NATS 已設定且 channel policy 允許 peer 與 skill 時才會執行。

部署型態 #

型態適用情境NATS 驗證備註
本機開發單機測兩個 bot無驗證或 dev token最快確認流程。
內部輕量部署私有可信網路、低維運負擔TLS 加 NATS_TOKEN只能搭配 private/firewalled listener 與 A2A_PRODUCTION_SECURITY=false
強化正式環境較嚴格 production 或多 host 暴露NATS_CREDS_FILE NKey/JWTA2A_PRODUCTION_SECURITY=true 時必須使用。
HA 正式環境NATS 可用性是關鍵NKey/JWT 加 JetStream cluster選用;只有在可承擔維運成本時使用。

多數私有部署可以先從一個 private JetStream node 開始,搭配持久化儲存、TLS、token authentication、localhost-only monitoring 與 host firewall。風險模型需要時再升級到 NKey/JWT 或 cluster。

前置條件 #

啟用 A2A 前:

  1. 每個 bot 都必須已經能作為一般 Discord bot 正常運作。
  2. 每個 bot 必須有自己的 DISCORD_TOKEN
  3. 每個 bot 建議有自己的 DATA_DIR;不要在不同 bot identity 之間共用狀態。
  4. 每個 bot 都需要穩定的 A2A_AGENT_ID
  5. NATS 必須啟用 JetStream。
  6. bot process environment 必須注入 A2A 變數。bot 不會自行載入 .env
  7. 要使用 A2A 的 Discord channel 必須已用 /cwd/start 初始化。

安裝 NATS Server 與 CLI #

依照官方文件安裝 NATS server 與 CLI:

確認指令可用:

nats-server --version
nats --version

本機開發 NATS #

使用 repository 內的開發設定啟動:

nats-server -c dev/nats.conf

確認 JetStream:

nats --server nats://127.0.0.1:4222 server check jetstream
nats --server nats://127.0.0.1:4222 stream ls

當 NATS credential 允許 JetStream setup 時,第一次 bot 啟動會建立 task、control、event streams 與 runtime consumers。Peer publish 會建立或更新 peer KV bucket。Object store 會在寫入 A2A artifact 時 lazy create。

正式環境 NATS Server #

內部輕量 profile #

只適合 private/internal deployments,且 operator 明確接受 single-node 與 shared-token tradeoff。

最低要求:

NATS config skeleton 範例:

server_name: a2a-nats
port: 4222
http: 127.0.0.1:8222

jetstream {
  store_dir: "/var/lib/nats/jetstream"
}

authorization {
  token: "<set-a-random-token>"
}

tls {
  cert_file: "/etc/nats/certs/server.crt"
  key_file: "/etc/nats/certs/server.key"
  ca_file: "/etc/nats/certs/ca.pem"
}

這個 profile 的安全性低於 per-agent credentials。不要把 NATS listener 廣泛暴露。

強化正式環境 profile #

強化正式環境請使用 NKey/JWT credentials:

A2A_PRODUCTION_SECURITY=true
NATS_CREDS_FILE=/etc/kiro-discord-bot/nats/bot.creds
NATS_TOKEN=
NATS_TLS_CA_FILE=/etc/kiro-discord-bot/nats/ca.pem

NATS_TLS_CA_FILE 只負責驗證 NATS server certificate,不是 client authentication。當 A2A_PRODUCTION_SECURITY=true 時,NATS_TOKEN 不能作為唯一 production credential。

設定 Bot A #

每個 bot process 使用一個穩定 base identity。Runtime mode 會針對每個 enabled/discoverable Discord channel 或 thread policy 發布 runtime peer。

Bot A 的內部輕量 .env 範例:

DISCORD_TOKEN=<bot-a-discord-token>
DISCORD_GUILD_ID=<guild-id>
DEFAULT_CWD=/projects
DATA_DIR=/var/lib/kiro-discord-bot/bot-a

NATS_URL=tls://nats.example.internal:4222
NATS_TOKEN=<internal-token>
NATS_CREDS_FILE=
NATS_TLS_CA_FILE=/etc/kiro-discord-bot/nats/ca.pem

A2A_CONFIRMATION_SECRET=<random-secret>
A2A_AGENT_ID=adam-n200
A2A_RUNTIME_ID_MODE=runtime
A2A_AGENT_NAME=Adam
A2A_AGENT_DESCRIPTION=General project assistant. No secrets, paths, hosts, or user data.
A2A_PRODUCTION_SECURITY=false
A2A_REQUIRE_CONFIRMATION_FOR_REMOTE=true
A2A_AUTO_DELEGATE_ENABLED=false
A2A_MAX_DELEGATION_DEPTH=1

設定 Bot B #

Bot B 必須使用不同的 Discord token、DATA_DIRA2A_AGENT_ID

DISCORD_TOKEN=<bot-b-discord-token>
DISCORD_GUILD_ID=<guild-id-or-other-guild-id>
DEFAULT_CWD=/projects
DATA_DIR=/var/lib/kiro-discord-bot/bot-b

NATS_URL=tls://nats.example.internal:4222
NATS_TOKEN=<internal-token>
NATS_CREDS_FILE=
NATS_TLS_CA_FILE=/etc/kiro-discord-bot/nats/ca.pem

A2A_CONFIRMATION_SECRET=<random-secret>
A2A_AGENT_ID=eve-local
A2A_RUNTIME_ID_MODE=runtime
A2A_AGENT_NAME=Eve
A2A_AGENT_DESCRIPTION=Backend review assistant. No secrets, paths, hosts, or user data.
A2A_PRODUCTION_SECURITY=false
A2A_REQUIRE_CONFIRMATION_FOR_REMOTE=true
A2A_AUTO_DELEGATE_ENABLED=false
A2A_MAX_DELEGATION_DEPTH=1

不要把 raw credentials、private paths、hostnames、Discord IDs 或 internal topology 放進 A2A_AGENT_DESCRIPTION;peer cards 會被其他 A2A participants 發現。

啟動或重啟 Bot #

Foreground smoke:

set -a
. ./.env
set +a
./kiro-discord-bot

Systemd 範例:

sudo systemctl restart kiro-discord-bot
sudo systemctl status kiro-discord-bot

預期 log markers 包含 NATS enabled、transport consumers started 與 bot running。疑難排解時不要印出完整 environment 或 secrets。

/doctor 驗證 #

在每個要使用 A2A 的 Discord channel 執行:

/doctor

預期:

/doctor 顯示 A2A disabled,先檢查 service environment。NATS_URL 是開關。

在 Discord 啟用 Channel Policy #

環境變數只是在 process 層啟用 A2A;每個 Discord channel 仍需要明確 policy。

先列出可見 peers:

/a2a peers

允許一個 peer runtime 將一般任務送進這個 channel:

/a2a allow peer_agent:<peer-runtime-agent-id>

這個 receiver-side consent 會立即套用到 exact runtime ID。它不是 wildcard bot-prefix grant、不是雙向 trust,也不設定 co-present reply mode。

Co-present 需要雙方 policy、Discord send permissions 與 delivery readiness 都成立。trusted=true 本身不夠。

Agents 可以使用內建高階 bot-tools MCP tools:

不要直接編輯 data/a2a/*.sqlite

發送測試任務 #

套用 consent 後,發送 delegated task:

/a2a ask peer_agent:<peer-runtime-agent-id> message:"Please reply with a short A2A smoke-test confirmation."

查看狀態:

/a2a status

成功送出只代表 task 已 durable queued,不代表遠端 bot 已接受或完成。請使用 /a2a statusbot_a2a_task_status 查看權威狀態。

常見 TaskStore 狀態:

狀態意義
TASK_STATE_SUBMITTED本地 bot 已排入 task。
TASK_STATE_WORKING遠端 runtime 已接受 task 或送出進度。
TASK_STATE_COMPLETED遠端 runtime 已成功完成。
TASK_STATE_FAILEDRuntime 或 execution failure。
TASK_STATE_CANCELEDTask 被取消。
TASK_STATE_REJECTEDPolicy、skill、quota、auth 或 runtime validation 拒絕 task。

accepted event 會作為 task progress 記錄,並把 durable task state 移到 TASK_STATE_WORKING;它不是獨立的 TaskStore state。

Delivery Modes #

模式行為
proxy 或 saferequester bot 轉送遠端結果。這是跨 server 最安全的預設。
transparent結果更直接暴露,但仍受 policy 控制。
co_present兩個 bot 可以在同一個 Discord channel 或 thread 發言。需要雙方 policy 與 Discord 權限。

先使用 safe/proxy。只有在雙方 operator 都預期直接同 channel 協作時才切到 co-present。

疑難排解 #

症狀可能原因檢查
/doctor 顯示 A2A disabledNATS_URL 為空或未注入 service檢查 process manager environment。
Startup 因缺少 A2A_AGENT_ID 失敗設了 NATS_URL 但沒有穩定 agent ID設定 A2A_AGENT_ID
Startup 拒絕 token-only productionA2A_PRODUCTION_SECURITY=true 但沒有 NATS_CREDS_FILE使用 NKey/JWT creds,或明確選擇 internal lightweight profile。
看不到 peerpeer card 未發布、ACL 問題、KV stale、runtime mode 錯誤執行 /doctor/a2a peers,並檢查 NATS logs。
Delegation 被拒絕Policy 不允許 sender、skill 或 target執行 /a2a peers/a2a allow,或用 bot-tools 檢查 readiness。
Co-present 不生效缺少 co_present_from_runtimes、target channel allowlist 或 Discord send permission查看 /doctor/a2a peers 的 delivery readiness。
Events 延遲JetStream redelivery 或 remote runtime 延遲查看 /a2a status;idempotency 應避免重複 terminal delivery。

回滾 #

停用 A2A 且不改變一般 Discord bot 行為:

  1. 設定 NATS_URL=""
  2. 重啟或 drain bot。
  3. 執行 /doctor
  4. 發送一般非 A2A Discord 訊息,確認 bot 正常回覆。
  5. 除非 retention/postmortem 流程允許,保留 DATA_DIR

Rollback 不需要刪除 A2A SQLite rows 或 JetStream state。