新增功能
This commit is contained in:
+28
-15
@@ -42,11 +42,21 @@ _STORE = ConversationStore(os.path.join(_ROOT, "conversations.json"))
|
||||
|
||||
|
||||
def _mask_key(key: str) -> str:
|
||||
if not key or len(key) < 10:
|
||||
if not key:
|
||||
return ""
|
||||
if len(key) < 10:
|
||||
return "***"
|
||||
return key[:6] + "…" + key[-4:]
|
||||
|
||||
|
||||
def _is_secret_config_key(key: str) -> bool:
|
||||
upper = str(key).upper()
|
||||
return any(
|
||||
marker in upper
|
||||
for marker in ("KEY", "TOKEN", "SECRET", "PASSWORD", "CREDENTIAL")
|
||||
)
|
||||
|
||||
|
||||
def _reload_store() -> ConversationStore:
|
||||
"""每次读取前重新加载,避免外部进程写盘后读到旧缓存。"""
|
||||
global _STORE
|
||||
@@ -115,12 +125,13 @@ def get_status() -> dict[str, Any]:
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def get_ai_config(reveal_api_key: bool = False) -> dict[str, Any]:
|
||||
"""读取当前 AI 配置(默认脱敏 API Key;reveal_api_key=true 时显示完整 Key)。"""
|
||||
def get_ai_config() -> dict[str, Any]:
|
||||
"""读取当前 AI 配置;所有密码、Key、Token 和 Secret 始终脱敏。"""
|
||||
ai_config.load_settings()
|
||||
data = {k: getattr(ai_config, k) for k in ai_config.CONFIGURABLE_KEYS}
|
||||
if not reveal_api_key and "AI_API_KEY" in data:
|
||||
data["AI_API_KEY"] = _mask_key(str(data["AI_API_KEY"]))
|
||||
for key in tuple(data):
|
||||
if _is_secret_config_key(key):
|
||||
data[key] = _mask_key(str(data[key] or ""))
|
||||
data["system_prompt_preview"] = ai_config.build_system_prompt()[:500]
|
||||
return data
|
||||
|
||||
@@ -128,7 +139,7 @@ def get_ai_config(reveal_api_key: bool = False) -> dict[str, Any]:
|
||||
@mcp.tool()
|
||||
def update_ai_config(updates: dict[str, Any]) -> dict[str, Any]:
|
||||
"""
|
||||
更新 AI 配置并写入 ai_settings.json。
|
||||
更新 AI 配置并写入 ai_settings.local.json。
|
||||
只允许修改 CONFIGURABLE_KEYS 中的字段,例如:
|
||||
{"AI_AGENT_NAME": "高兴亮", "AI_COUNTER_INSULT_ENABLED": false, "AI_TEMPERATURE": 0.8}
|
||||
"""
|
||||
@@ -136,7 +147,7 @@ def update_ai_config(updates: dict[str, Any]) -> dict[str, Any]:
|
||||
changed = {}
|
||||
ignored = []
|
||||
for k, v in (updates or {}).items():
|
||||
if k not in ai_config.CONFIGURABLE_KEYS:
|
||||
if k not in ai_config.CONFIGURABLE_KEYS or _is_secret_config_key(k):
|
||||
ignored.append(k)
|
||||
continue
|
||||
# 轻量类型校正
|
||||
@@ -156,13 +167,9 @@ def update_ai_config(updates: dict[str, Any]) -> dict[str, Any]:
|
||||
except Exception:
|
||||
ignored.append(k)
|
||||
continue
|
||||
setattr(ai_config, k, v)
|
||||
changed[k] = v if k != "AI_API_KEY" else _mask_key(str(v))
|
||||
changed[k] = v
|
||||
|
||||
if "AI_AGENT_NAME" in changed or "AI_HOSPITAL_NAME" in changed:
|
||||
ai_config.AI_SYSTEM_PROMPT = ai_config.build_system_prompt()
|
||||
|
||||
ai_config.save_settings()
|
||||
ai_config.apply_settings(changed, persist=True)
|
||||
return {"ok": True, "changed": changed, "ignored": ignored}
|
||||
|
||||
|
||||
@@ -240,7 +247,13 @@ def draft_reply(
|
||||
history = store.history(session_id)
|
||||
|
||||
try:
|
||||
reply = call_ai_text(message.strip(), history=history)
|
||||
reply = call_ai_text(
|
||||
message.strip(),
|
||||
history=history,
|
||||
# use_history=False must also disable the Chat project's remote
|
||||
# conversation, not merely omit the local archive.
|
||||
session_id=session_id if use_history else None,
|
||||
)
|
||||
except Exception as e:
|
||||
return {"ok": False, "error": str(e)}
|
||||
|
||||
@@ -299,7 +312,7 @@ def resource_sessions() -> str:
|
||||
@mcp.resource("wechat-rpa://config")
|
||||
def resource_config() -> str:
|
||||
"""AI 配置 JSON(Key 脱敏)。"""
|
||||
return json.dumps(get_ai_config(False), ensure_ascii=False, indent=2)
|
||||
return json.dumps(get_ai_config(), ensure_ascii=False, indent=2)
|
||||
|
||||
|
||||
@mcp.prompt()
|
||||
|
||||
Reference in New Issue
Block a user