# ADR-019: Telegram Bot Agentic Conversation Layer

- **Status**: Accepted
- **Date**: 2026-05-02
- **Deciders**: 統帥
- **Related**: ADR-001（三 Agent 學習分工）、ADR-012（Agent Action Ladder）、ADR-015（Telegram Menu Restoration）、ADR-018（四 Agent Control Plane）

## Context

ADR-018 已定義 Hermes / NemoTron / OpenClaw / ElephantAlpha 四 Agent control plane 的責任邊界。OpenClaw 是 L3 Strategist，負責高品質策略、報告、長期洞察。

但實作上，Telegram Bot 的互動層**完全繞過 OpenClaw 的決策能力**：

1. **菜單按鈕走快車道** — `cmd:X` callback ([routes/openclaw_bot_routes.py:4412](../../routes/openclaw_bot_routes.py#L4412)) 直接呼叫寫死 handler（如 `_generate_ppt_cmd:2189`），不經 agent。
2. **NL chat 是 last-resort fallback** — `openclaw_answer:4176` 已具備 Gemini Function Calling + NIM tool use 能力，但只在用戶輸入文字「沒匹配任何 keyword/state」時才被呼叫（[telegram_bot_service.py:933](../../services/telegram_bot_service.py#L933)）。
3. **Rigid default + 靜默空白** — `_generate_ppt_cmd` 月報分支 [line 2293](../../routes/openclaw_bot_routes.py#L2293) 用 `now.year, now.month` 當預設，若 ETL 未進當月資料，PPT 生成「本月業績為零」的虛文，無提示無詢問。
4. **無對話 state** — 每條訊息獨立，無 multi-turn confirmation、無 carry-over slot。
5. **EventRouter 覆蓋 1.8%** — 21 個 telegram 發送點各自為政（記憶 `feedback_agent_action_ladder.md`、`reference_telegram_endpoints_map.md`）。

**痛點觸發**（2026-05-02 真實事件）：用戶在月初 5/2 點 ppt:monthly → 系統預設查 5 月 → DB 最新資料只到 4/25 → AI 老實寫「業績為零」→ PPT 內容大量空白 → 用戶反映「老是異常你都無感嗎」。

## Decision

採用「**Agent-First Conversation Layer**」原則：Telegram Bot 互動層的所有用戶輸入（cmd / menu / NL）都經過 OpenClaw agent 決策層，菜單按鈕降級為「agent suggestion shortcuts」，而非繞過 agent 的快車道。

### 五條互動原則

| # | 原則 | 含意 |
|---|------|------|
| 1 | **單一決策入口** | 所有 cmd:X / menu:X / NL message 統一進 `openclaw_decide(intent, args, ctx)`，agent 自決下一步動作 |
| 2 | **資料缺口優先告知，不靜默** | Agent 在執行任何資料查詢前，先 probe `latest_date()` / `query_available_*()`；缺資料時主動 inline ask，不出空白報告 |
| 3 | **NL 對話一等公民** | 用戶可用「我要看上個月月報」「最近一週的銷售」等 NL 觸發，與按鈕等價，agent 用 tool calling 解析 |
| 4 | **Multi-turn state** | 加 `services/openclaw_session.py` 管 chat_id 對話狀態，支援 carry-over slot（如「剛問月份 → 用戶答 4 → 接續執行」）|
| 5 | **EventRouter 統一出口** | 所有 telegram 發送經 EventRouter；agent 的 ask / answer / report 也走同管道，便於去重/降級/重送 |

### 邊界（不做什麼）

- 不取代 ADR-018 的 control plane 責任分工（仍是四 agent）
- 不繞過 ADR-012 的 L0/L1/L2/L3 信任邊界（高風險 action 仍走 HITL）
- 不重寫 telegram_templates.py（31 個模板繼續用）
- 不改 webhook/polling 雙路徑架構（ADR-008 已定）
- 不改 dedup guard（commit 1a886d9 已部署）

### 範圍

- ✅ `routes/openclaw_bot_routes.py` cmd dispatch 改造
- ✅ `services/telegram_bot_service.py` handle_message NL → agent 路徑
- ✅ 新增 `services/openclaw_session.py` 對話 state
- ✅ 新增 `services/openclaw_tools.py` agent tool registry
- ✅ EventRouter 21 個發送點遷移（refactor-specialist 範圍）
- ❌ Hermes embedding worker 不動
- ❌ NemoTron / ElephantAlpha 內部邏輯不動

## Alternatives Considered

| 方案 | 不採用原因 |
|------|----------|
| A. 只補 freshness gate（band-aid） | 同類 bug 散在 daily/weekly/strategy/competitor/promo 多處，補不完，治標不治本 |
| B. 引入外部 agent framework (LangGraph/AutoGen) | 黑盒、難審計、跨 agent 通訊已有 EventRouter 能擴展，不增加依賴 |
| C. 直接 deprecate cmd:X 路徑只留 NL | 用戶習慣按鈕互動，移除會破壞 UX；菜單可以保留為 agent suggestion |
| D. 把 OpenClaw 換成 ElephantAlpha 做對話入口 | ADR-018 已分工：ElephantAlpha 是 orchestrator 不是對話 agent；OpenClaw 才是 |

## Consequences

正面：
- PPT 空白等「rigid default」類 bug 一次性根除（agent 主動 detect 缺口）
- NL 對話和按鈕互動統一，用戶體驗一致
- Multi-turn state 讓複雜場景（如「上個月 vs 過去 3 個月」對比）變可能
- EventRouter 覆蓋率 1.8% → 80%，系統可觀測性大幅提升

風險：
- Phase 3 影響 21 個 cmd 行為，需灰度 + feature flag + e2e regression
- Agent 多一層決策，每個 cmd 增加 200-500ms latency（NIM/Gemini call）
- 對話 state 引入新故障面（session race / memory leak）
- 全部完成需 4-6 週工程，期間需保持向下相容

降級策略：
- Agent 失敗 → 回退原 cmd:X 寫死 handler（feature flag off）
- Tool call timeout → 用 cached response or template fallback
- Session lookup fail → 視為新對話，不阻斷主流程

## Implementation Plan

分 6 Phase 漸進交付，每 Phase 可獨立上線/回滾：

| Phase | 目標 | 工時 | 可獨立 ship |
|-------|------|------|-----------|
| 0 | 本 ADR + 計畫對齊 | 1h | ✅ |
| 1 | PPT 3 個 handler 補 freshness gate（止血）| 2h | ✅ |
| 2 | OpenClaw tool registry（query_*, ppt 等變 tool）| 1d | ✅ |
| 3 | cmd:X dispatch 接入 agent.decide()（feature flag 灰度）| 2d | ✅ |
| 4 | Multi-turn state（services/openclaw_session.py）| 1d | ✅ |
| 5 | EventRouter 21 發送點遷移（refactor-specialist）| 2-3d | ✅ |
| 6 | Proactive 09:00 資料新鮮度 probe + agent 主動通知 | 1d | ✅ |

每 Phase 後驗收：
- Phase 1: PPT 空白事件 = 0
- Phase 3: 21 cmd regression test pass + agent 接管率 100%
- Phase 5: EventRouter coverage 1.8% → 80%

## References

- ADR-001 三 Agent 學習分工
- ADR-012 Agent Action Ladder
- ADR-015 Telegram Menu Restoration
- ADR-018 四 Agent Control Plane
- 記憶：`feedback_agent_action_ladder.md`、`reference_telegram_endpoints_map.md`、`feedback_iterative_rollout.md`
- 觸發事件：2026-05-02 用戶 PPT 月報空白回報
