Files
deerflow-code/offline-backend-20260512/backend/packages/harness/deerflow/agents/deep_research/engine.py
T
2026-08-15 12:51:58 +08:00

64 lines
2.4 KiB
Python

"""DeepResearchEngine — mode-dispatching entry point (§12.1).
The engine selects the appropriate runner for the request's ``mode`` and hands
it the assembled :class:`AdapterBundle`. It is a thin dispatcher: all research
logic lives in the runners; all infrastructure wiring lives in the adapter
construction (done by the executor before calling ``run``).
``basic``/``quick`` use the compact path. ``detailed`` and ``deep`` use their
dedicated runners; ``multi_agent`` runs the LangGraph editor/researcher/writer/
reviewer workflow with durable plan-review pause and resume.
"""
from __future__ import annotations
import logging
from typing import TYPE_CHECKING
from deerflow.agents.deep_research.runners.basic import BasicRunner
from deerflow.agents.deep_research.runners.deep import DeepRunner
from deerflow.agents.deep_research.runners.detailed import DetailedRunner
from deerflow.agents.deep_research.runners.multi_agent import MultiAgentRunner
from deerflow.agents.deep_research.types import DeepResearchRequest, DeepResearchResult
if TYPE_CHECKING:
from deerflow.agents.deep_research.cancellation import CancellationToken
from deerflow.agents.deep_research.types import AdapterBundle
logger = logging.getLogger(__name__)
class DeepResearchEngine:
"""Dispatches a research request to the mode-appropriate runner."""
def __init__(self) -> None:
self._basic = BasicRunner()
self._detailed = DetailedRunner()
self._deep = DeepRunner()
self._multi_agent = MultiAgentRunner()
async def run(
self,
request: DeepResearchRequest,
*,
adapters: AdapterBundle,
cancellation: CancellationToken | None = None,
) -> DeepResearchResult:
mode = request.config.mode
if mode in ("basic", "quick"):
return await self._basic.run(request, adapters, cancellation)
if mode == "detailed":
return await self._detailed.run(request, adapters, cancellation)
if mode == "deep":
return await self._deep.run(request, adapters, cancellation)
if mode == "multi_agent":
return await self._multi_agent.run(request, adapters, cancellation)
# Phase 1 scope guard — these modes are planned for later phases.
raise NotImplementedError(
f"Research mode '{mode}' is not implemented. "
"Available modes: quick, basic, detailed, deep, multi_agent."
)
__all__ = ["DeepResearchEngine"]