projects/robot/general-agent 所有用户共享会导致文件/会话产物互串。
get_general_agent_runtime_config 生成 project_dir_key=general-agent-{user},
v3 chat 优先用它作为 create_project_directory 的目录标识。
普通 bot 不返回 project_dir_key,行为不变。
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
107 lines
4.1 KiB
Python
107 lines
4.1 KiB
Python
import json
|
||
import os
|
||
from pathlib import Path
|
||
from typing import Any, Dict, Optional
|
||
|
||
from fastapi import HTTPException
|
||
|
||
from utils.settings import NEW_API_BASE_URL
|
||
|
||
GENERAL_AGENT_CONFIG_PATH = Path(os.getenv("GENERAL_AGENT_CONFIG_PATH", "config/general_agent.json"))
|
||
|
||
|
||
def load_general_agent_config() -> Dict[str, Any]:
|
||
if not GENERAL_AGENT_CONFIG_PATH.exists():
|
||
raise HTTPException(status_code=500, detail="General agent config not found")
|
||
|
||
try:
|
||
with GENERAL_AGENT_CONFIG_PATH.open("r", encoding="utf-8") as file:
|
||
config = json.load(file)
|
||
except json.JSONDecodeError as error:
|
||
raise HTTPException(status_code=500, detail=f"Invalid general agent config: {error}")
|
||
|
||
if not isinstance(config, dict):
|
||
raise HTTPException(status_code=500, detail="General agent config must be an object")
|
||
|
||
if not config.get("enabled", False):
|
||
raise HTTPException(status_code=404, detail="General agent is disabled")
|
||
|
||
required_fields = ["bot_id", "name", "model_id", "system_prompt"]
|
||
missing_fields = [field for field in required_fields if not config.get(field)]
|
||
if missing_fields:
|
||
raise HTTPException(status_code=500, detail=f"General agent config missing fields: {', '.join(missing_fields)}")
|
||
|
||
return config
|
||
|
||
|
||
def get_general_agent_id() -> str:
|
||
return str(load_general_agent_config()["bot_id"])
|
||
|
||
|
||
def is_general_agent_id(bot_id: Optional[str]) -> bool:
|
||
if not bot_id:
|
||
return False
|
||
|
||
try:
|
||
config = load_general_agent_config()
|
||
except HTTPException:
|
||
return False
|
||
|
||
return str(bot_id) == str(config.get("bot_id"))
|
||
|
||
|
||
def _as_list(value: Any, *, split_newlines: bool = False) -> list:
|
||
if value is None:
|
||
return []
|
||
if isinstance(value, list):
|
||
return value
|
||
if isinstance(value, str):
|
||
separator = "\n" if split_newlines else ","
|
||
return [item.strip() for item in value.split(separator) if item.strip()]
|
||
return []
|
||
|
||
|
||
def get_general_agent_settings() -> Dict[str, Any]:
|
||
config = load_general_agent_config()
|
||
settings = dict(config)
|
||
settings["suggestions"] = _as_list(settings.get("suggestions"), split_newlines=True)
|
||
settings["dataset_ids"] = _as_list(settings.get("dataset_ids"))
|
||
settings["skills"] = _as_list(settings.get("skills"))
|
||
settings["shell_env"] = settings.get("shell_env") or {}
|
||
settings["mcp_settings"] = settings.get("mcp_settings") or []
|
||
return settings
|
||
|
||
|
||
def get_general_agent_runtime_config(user_identifier: Optional[str] = None) -> Dict[str, Any]:
|
||
settings = get_general_agent_settings()
|
||
model_id = settings.get("model_id", "")
|
||
bot_id = settings.get("bot_id", "general-agent")
|
||
|
||
# 按用户隔离工作目录:projects/robot/general-agent-{user}
|
||
raw_user = user_identifier or "anonymous"
|
||
safe_user = "".join(c if c.isalnum() or c in "-_" else "_" for c in raw_user) or "anonymous"
|
||
project_dir_key = f"{bot_id}-{safe_user}"
|
||
|
||
return {
|
||
"name": settings.get("name", "通用智能体"),
|
||
"model": model_id,
|
||
"api_key": settings.get("api_key", ""),
|
||
"model_server": settings.get("model_server") or (NEW_API_BASE_URL.rstrip("/") + "/v1" if NEW_API_BASE_URL else ""),
|
||
"language": settings.get("language", "zh"),
|
||
"dataset_ids": settings.get("dataset_ids", []),
|
||
"system_prompt": settings.get("system_prompt", ""),
|
||
"user_identifier": user_identifier,
|
||
"enable_memori": settings.get("enable_memori", False),
|
||
"tool_response": settings.get("tool_response", False),
|
||
"enable_thinking": settings.get("enable_thinking", False),
|
||
"skills": settings.get("skills", []),
|
||
"description": settings.get("description", ""),
|
||
"suggestions": settings.get("suggestions", []),
|
||
"shell_env": settings.get("shell_env") or {},
|
||
"voice_speaker": settings.get("voice_speaker", ""),
|
||
"voice_system_role": settings.get("voice_system_role", ""),
|
||
"voice_speaking_style": settings.get("voice_speaking_style", ""),
|
||
"mcp_settings": settings.get("mcp_settings", []),
|
||
"project_dir_key": project_dir_key,
|
||
}
|