refactor(beaver): 移除Hermes相关引用和迁移代码,完善Beaver后端主线实现

移除了所有Hermes相关的命名引用,包括:
- 从.gitignore中清理相关构建缓存文件
- 将README中的beaver-home路径配置更新
- 完善backend/README.md文档说明Beaver后端主线实现
- 移除Hermes风格的相关注释和兼容性代码
- 清理nanobot环境变量兼容性处理
- 删除技能迁移和服务迁移相关功能代码
- 更新测试用例中相关命名和函数名

BREAKING CHANGE: 移除了Hermes迁移相关API和CLI命令,不再支持nanobot环境变量兼容性
This commit is contained in:
2026-05-14 17:20:32 +08:00
parent b59968167e
commit 3b0af173cc
57 changed files with 245 additions and 4109 deletions

View File

@ -23,7 +23,6 @@ from beaver.foundation.models import CronExecutionResult, CronRunRecord
from beaver.integrations.mcp import MCPConnectionManager
from beaver.services.agent_service import NOTIFICATION_SESSION_ID, AgentService
from beaver.services.cron_service import CronService, schedule_from_api
from beaver.services.skill_migration import SkillMigrationService
from beaver.services.skillhub_service import SkillHubService
from beaver.skills.learning import SkillLearningWorker, SkillLearningWorkerConfig
from beaver.skills.catalog.utils import parse_frontmatter
@ -305,7 +304,7 @@ def create_app(
)
app.state.auth_tokens = {}
app.state.handoff_codes = {}
app.state.auth_file = Path(os.getenv("BEAVER_AUTH_FILE") or os.getenv("NANOBOT_AUTH_FILE") or "")
app.state.auth_file = Path(os.getenv("BEAVER_AUTH_FILE") or "")
max_file_size = 50 * 1024 * 1024
@app.get("/api/ping", response_model=WebStatusResponse)
@ -427,7 +426,6 @@ def create_app(
_clean_text(payload.get("base_url"))
or config.backend_identity.public_base_url
or os.getenv("BEAVER_FRONTEND_PUBLIC_BASE_URL")
or os.getenv("NANOBOT_FRONTEND_PUBLIC_BASE_URL")
or str(request.base_url).rstrip("/")
)
frontend_base_url = _clean_text(payload.get("frontend_base_url")) or public_base_url
@ -526,7 +524,7 @@ def create_app(
return {
"id": username,
"username": username,
"email": os.getenv("BEAVER_BACKEND_IDENTITY__EMAIL") or os.getenv("NANOBOT_BACKEND_IDENTITY__EMAIL", ""),
"email": os.getenv("BEAVER_BACKEND_IDENTITY__EMAIL", ""),
"role": "owner",
"quota_tier": "single-user",
}
@ -1184,30 +1182,6 @@ def create_app(
)
return result
@app.get("/api/tools/servers")
async def list_tool_servers(request: Request) -> list[dict[str, Any]]:
return await list_mcp_servers(request)
@app.get("/api/tools")
async def list_tools(request: Request) -> dict[str, Any]:
servers = await list_mcp_servers(request)
tool_groups = await list_mcp_tools(request)
server_map = {server["id"]: server for server in servers}
grouped = {"local": [], "online": []}
for group in tool_groups:
server = server_map.get(group["server_id"], {})
kind = str(server.get("kind") or "online")
item = {
**group,
"server_name": server.get("name") or group["server_id"],
"transport": server.get("transport"),
"kind": kind,
"category": server.get("category") or kind,
"status": server.get("status"),
}
grouped["local" if kind == "local" else "online"].append(item)
return {"servers": servers, "groups": grouped}
@app.get("/api/skills")
async def list_skills(request: Request) -> list[dict[str, Any]]:
loaded = get_agent_service(request).create_loop().boot()
@ -1301,19 +1275,6 @@ def create_app(
raise HTTPException(status_code=400, detail=str(exc)) from exc
return draft
@app.post("/api/skills/migrate")
async def migrate_skills(request: Request) -> dict[str, Any]:
loaded = get_agent_service(request).create_loop().boot()
return SkillMigrationService(loaded.skill_spec_store).migrate_all() # type: ignore[arg-type]
@app.get("/api/skills/migration-manifest")
async def get_skill_migration_manifest(request: Request) -> dict[str, Any]:
loaded = get_agent_service(request).create_loop().boot()
path = loaded.workspace / "skill_migration_manifest.json"
if not path.exists():
return {"included": [], "skipped": []}
return json.loads(path.read_text(encoding="utf-8"))
@app.get("/api/marketplaces/skills/search")
async def search_skillhub(
request: Request,
@ -2482,7 +2443,7 @@ def _provider_enabled(provider_name: str, provider_cfg: Any) -> bool:
def _auth_file_path() -> Path:
raw = os.getenv("BEAVER_AUTH_FILE") or os.getenv("NANOBOT_AUTH_FILE")
raw = os.getenv("BEAVER_AUTH_FILE")
if raw:
return Path(raw)
return Path.home() / ".beaver" / "web_auth_users.json"
@ -2542,7 +2503,7 @@ def _issue_web_token(app: FastAPI, username: str) -> str:
def _handoff_ttl_seconds() -> int:
raw = os.getenv("NANOBOT_HANDOFF_CODE_TTL_SECONDS", "90").strip()
raw = os.getenv("BEAVER_HANDOFF_CODE_TTL_SECONDS", "90").strip()
try:
return max(15, int(raw))
except ValueError:
@ -2550,7 +2511,7 @@ def _handoff_ttl_seconds() -> int:
def _handoff_replay_window_seconds() -> int:
raw = os.getenv("NANOBOT_HANDOFF_REPLAY_WINDOW_SECONDS", "15").strip()
raw = os.getenv("BEAVER_HANDOFF_REPLAY_WINDOW_SECONDS", "15").strip()
try:
return max(1, int(raw))
except ValueError:
@ -2637,22 +2598,18 @@ def _require_web_user(app: FastAPI, authorization: str | None) -> str:
def _backend_connection_view(request: Request) -> dict[str, Any]:
public_base_url = (
os.getenv("BEAVER_BACKEND_IDENTITY__PUBLIC_BASE_URL")
or os.getenv("NANOBOT_BACKEND_IDENTITY__PUBLIC_BASE_URL")
or os.getenv("BEAVER_FRONTEND_PUBLIC_BASE_URL")
or os.getenv("NANOBOT_FRONTEND_PUBLIC_BASE_URL")
or str(request.base_url).rstrip("/")
)
backend_id = (
os.getenv("BEAVER_BACKEND_IDENTITY__BACKEND_ID")
or os.getenv("NANOBOT_BACKEND_IDENTITY__BACKEND_ID")
or os.getenv("BEAVER_BACKEND_IDENTITY__CLIENT_ID")
or os.getenv("NANOBOT_BACKEND_IDENTITY__CLIENT_ID")
)
client_id = os.getenv("BEAVER_BACKEND_IDENTITY__CLIENT_ID") or os.getenv("NANOBOT_BACKEND_IDENTITY__CLIENT_ID") or backend_id
client_id = os.getenv("BEAVER_BACKEND_IDENTITY__CLIENT_ID") or backend_id
return {
"backend_id": backend_id,
"client_id": client_id,
"name": os.getenv("BEAVER_BACKEND_IDENTITY__NAME") or os.getenv("NANOBOT_BACKEND_IDENTITY__NAME") or backend_id,
"name": os.getenv("BEAVER_BACKEND_IDENTITY__NAME") or backend_id,
"public_base_url": public_base_url,
"api_base_url": public_base_url,
"frontend_base_url": public_base_url,
@ -2663,16 +2620,14 @@ def _backend_connection_view(request: Request) -> dict[str, Any]:
def _local_backend_view() -> dict[str, Any]:
return {
"backend_id": os.getenv("BEAVER_BACKEND_IDENTITY__BACKEND_ID") or os.getenv("NANOBOT_BACKEND_IDENTITY__BACKEND_ID"),
"client_id": os.getenv("BEAVER_BACKEND_IDENTITY__CLIENT_ID") or os.getenv("NANOBOT_BACKEND_IDENTITY__CLIENT_ID"),
"name": os.getenv("BEAVER_BACKEND_IDENTITY__NAME") or os.getenv("NANOBOT_BACKEND_IDENTITY__NAME"),
"backend_id": os.getenv("BEAVER_BACKEND_IDENTITY__BACKEND_ID"),
"client_id": os.getenv("BEAVER_BACKEND_IDENTITY__CLIENT_ID"),
"name": os.getenv("BEAVER_BACKEND_IDENTITY__NAME"),
"public_base_url": os.getenv("BEAVER_BACKEND_IDENTITY__PUBLIC_BASE_URL")
or os.getenv("NANOBOT_BACKEND_IDENTITY__PUBLIC_BASE_URL")
or os.getenv("BEAVER_FRONTEND_PUBLIC_BASE_URL")
or os.getenv("NANOBOT_FRONTEND_PUBLIC_BASE_URL"),
or os.getenv("BEAVER_FRONTEND_PUBLIC_BASE_URL"),
"authz": {
"enabled": (os.getenv("BEAVER_AUTHZ__ENABLED") or os.getenv("NANOBOT_AUTHZ__ENABLED", "")).strip() in {"1", "true", "True"},
"base_url": os.getenv("BEAVER_AUTHZ__BASE_URL") or os.getenv("NANOBOT_AUTHZ__BASE_URL"),
"enabled": os.getenv("BEAVER_AUTHZ__ENABLED", "").strip() in {"1", "true", "True"},
"base_url": os.getenv("BEAVER_AUTHZ__BASE_URL"),
},
}