## 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>
38 lines
1.1 KiB
Python
38 lines
1.1 KiB
Python
"""載入 .claude/agents/*.md 並解析 system prompt(ADR-095)
|
||
|
||
2026-04-24 Claude Sonnet 4.6 (WS4 Hermes NL)
|
||
"""
|
||
from __future__ import annotations
|
||
import pathlib
|
||
from functools import lru_cache
|
||
|
||
_AGENTS_DIR = pathlib.Path("/Users/ogt/awoooi/.claude/agents")
|
||
|
||
|
||
def _parse_agent_md(path: pathlib.Path) -> str:
|
||
"""去除 YAML frontmatter,回傳 body 作為 system prompt"""
|
||
text = path.read_text(encoding="utf-8")
|
||
# --- frontmatter ---
|
||
if text.startswith("---"):
|
||
end = text.find("---", 3)
|
||
if end != -1:
|
||
return text[end + 3:].strip()
|
||
return text.strip()
|
||
|
||
|
||
@lru_cache(maxsize=None)
|
||
def get_agent_system_prompt(agent_name: str) -> str | None:
|
||
"""
|
||
回傳指定 agent 的 system prompt。
|
||
若 .md 不存在回傳 None(caller 決定是否 fallback)。
|
||
"""
|
||
path = _AGENTS_DIR / f"{agent_name}.md"
|
||
if not path.exists():
|
||
return None
|
||
return _parse_agent_md(path)
|
||
|
||
|
||
def list_available_agents() -> list[str]:
|
||
"""回傳目前存在的 agent 名稱列表(無副檔名)"""
|
||
return [p.stem for p in sorted(_AGENTS_DIR.glob("*.md"))]
|