79 lines
2.8 KiB
Python
79 lines
2.8 KiB
Python
"""深度研究「收集员」内置 agent 的启动补建 seeder。
|
|
|
|
与 ``_ai_writing_seed.py`` / ``_roundtable_seed.py`` 完全同构:资源文件
|
|
(``_deep_research_seed_assets/deep-research-collector/``)是发布默认值的
|
|
唯一可信源,seeder 只在 ``.deer-flow/agents/deep-research-collector/``
|
|
目录缺失时字节级复制,**绝不覆盖**已存在目录(尊重 admin 在智能体管理页
|
|
的现场修改)。线上调优 SOUL 后请把改动写回资源文件,否则新机器补建出来
|
|
的还是旧版。
|
|
|
|
调用点:启动 lifespan(``app/gateway/app.py``),必须在 ``_sync_legacy_agents``
|
|
**之前**——后者会把目录 upsert 进 agents 表(`user_id IS NULL` 的内置
|
|
agent),所有用户即可在深度研究页使用。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
from deerflow.config.paths import get_paths
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
DEEP_RESEARCH_COLLECTOR_AGENT_ID = "deep-research-collector"
|
|
|
|
_ASSETS_DIR = Path(__file__).parent / "_deep_research_seed_assets"
|
|
_SEED_FILES: tuple[str, ...] = ("config.yaml", "SOUL.md")
|
|
|
|
|
|
def _ensure_one(agent_id: str) -> bool:
|
|
"""Copy the verified SOUL.md + config.yaml into ``.deer-flow/agents/<id>/``
|
|
if that directory is missing.
|
|
|
|
Returns True if the files were just created, False if the directory already
|
|
existed (never overwrite — respect local edits) or the seed assets are
|
|
missing.
|
|
"""
|
|
agent_dir = get_paths().agent_dir(agent_id)
|
|
if agent_dir.exists():
|
|
return False
|
|
|
|
src_dir = _ASSETS_DIR / agent_id
|
|
if not src_dir.is_dir():
|
|
logger.error(
|
|
"Missing seed assets for deep-research agent '%s' (expected at %s)",
|
|
agent_id,
|
|
src_dir,
|
|
)
|
|
return False
|
|
|
|
agent_dir.mkdir(parents=True, exist_ok=True)
|
|
for fname in _SEED_FILES:
|
|
src = src_dir / fname
|
|
if src.exists():
|
|
(agent_dir / fname).write_bytes(src.read_bytes())
|
|
return True
|
|
|
|
|
|
def ensure_deep_research_collector_agent() -> list[str]:
|
|
"""Seed the deep-research collector agent if its on-disk directory is
|
|
missing. Idempotent — fast no-op when it exists.
|
|
|
|
Returns the list of agent ids just created (empty when nothing needed
|
|
seeding). Errors are logged but never raised — a seed failure must not
|
|
block startup.
|
|
"""
|
|
created: list[str] = []
|
|
try:
|
|
if _ensure_one(DEEP_RESEARCH_COLLECTOR_AGENT_ID):
|
|
created.append(DEEP_RESEARCH_COLLECTOR_AGENT_ID)
|
|
except Exception:
|
|
logger.exception("Failed to seed deep-research collector agent")
|
|
if created:
|
|
logger.info("Seeded missing deep-research collector agent: %s", ", ".join(created))
|
|
return created
|
|
|
|
|
|
__all__ = ["DEEP_RESEARCH_COLLECTOR_AGENT_ID", "ensure_deep_research_collector_agent"]
|