Files
awoooi/apps/api/src/hermes/display_names.py
Your Name 2572ec46d2 feat(ws4): Hermes NL 自然語言介面 — 12-Agent Claude SDK 接入(ADR-094/095)
## hermes/ 套件(5 個新模組)

### display_names.py
- 12 agent 視覺識別表(emoji + hashtag + handle + short_name)
- format_response_header() 產生 Telegram 前綴

### agent_loader.py
- 解析 .claude/agents/*.md frontmatter → system prompt
- lru_cache 避免重複讀檔

### safety_hooks.py
- 移植 awoooi-guard.js 20 條 HARD BLOCK 規則(DENY_PATTERNS)
- 5 條 MUTATE_PATTERNS → 須走審批流

### nl_gateway.py
- Layer 1: 關鍵字正則路由(12 條規則,<10ms)
- Layer 3: DEFAULT_AGENT = "debugger"
- Claude Agent SDK query() 非同步串流,取 ResultMessage.result
- 安全降級:SDK error → 友好錯誤訊息

### telegram_webhook.py
- WS4 Hermes NL 接入(@tsenyangbot mention 或私訊觸發)
- HERMES_NL_ENABLED=False(feature flag 保護,預設關閉)

## telegram_gateway.py
- send_hermes_reply(text, chat_id, reply_to_message_id)
  無 500 字截斷,支援 Agent 長回覆

## config.py
- HERMES_NL_ENABLED: bool = False
- TELEGRAM_BOT_USERNAME: str = "tsenyangbot"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-25 02:10:06 +08:00

44 lines
2.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""ADR-095 12-Agent 視覺分派對照表
2026-04-24 Claude Sonnet 4.6 (WS4 Hermes NL)
"""
from __future__ import annotations
from dataclasses import dataclass
@dataclass(frozen=True)
class AgentVisual:
emoji: str
hashtag: str
handle: str # 文字 prefix非真 bot
short_name: str
# 鍵值 = .claude/agents/{key}.md 的檔名(不含副檔名)
AGENT_VISUALS: dict[str, AgentVisual] = {
"critic": AgentVisual("🔍", "#審查", "@hermes-critic", "找碴專家"),
"vuln-verifier": AgentVisual("🎯", "#漏洞驗證", "@hermes-verifier", "漏洞驗證官"),
"debugger": AgentVisual("🐛", "#除錯", "@hermes-debugger", "除錯偵探"),
"db-expert": AgentVisual("💾", "#資料庫", "@hermes-db", "DB 軍師"),
"planner": AgentVisual("📋", "#拆解", "@hermes-planner", "任務拆解官"),
"fullstack-engineer": AgentVisual("🛠️", "#工程", "@hermes-engineer", "全端工程師"),
"frontend-designer": AgentVisual("🎨", "#設計", "@hermes-designer", "前端設計師"),
"refactor-specialist": AgentVisual("♻️", "#重構", "@hermes-refactor", "重構專家"),
"migration-engineer": AgentVisual("🚚", "#升級", "@hermes-migration", "升級工程師"),
"onboarder": AgentVisual("🗺️", "#導覽", "@hermes-onboarder", "領航員"),
"tool-expert": AgentVisual("🧰", "#工具", "@hermes-tools", "工具專家"),
"web-researcher": AgentVisual("📚", "#文檔", "@hermes-web", "文獻研究員"),
}
DEFAULT_AGENT = "debugger" # Layer 3 fallback最常見「X 為什麼壞了」)
def get_visual(agent_name: str) -> AgentVisual:
return AGENT_VISUALS.get(agent_name, AGENT_VISUALS[DEFAULT_AGENT])
def format_response_header(agent_name: str) -> str:
"""回傳 Telegram 訊息的 agent 識別前綴,格式: emoji 短稱 handle hashtag"""
v = get_visual(agent_name)
return f"{v.emoji} **{v.short_name}** `{v.handle}` {v.hashtag}\n\n"