feat: 新增 agentfx 任务深链与研判报告入库流程

支持 goPath=agentfx 的 iframe 嵌入问答、内置研判助手种子与报告导入协助卡,并完善深度研究流式报告能力。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
董宏凯andCursor committed 2026-08-27 16:32:22 +08:00
1 parent 6e9e89a6cb
commit 52b9cbf707
34 files changed
+4488 -392

No files matched your search

@@ -5,12 +5,12 @@ from langchain.agents.middleware import AgentMiddleware
from langchain_core.runnables import RunnableConfig
from deerflow.agents.lead_agent.prompt import apply_prompt_template
from deerflow.agents.middlewares.clarification_middleware import ClarificationMiddleware
from deerflow.agents.middlewares.forced_research_middleware import (
FORCED_RESEARCH_AGENT_ID,
ForcedResearchMiddleware,
filter_forced_research_tools,
)
from deerflow.agents.middlewares.clarification_middleware import ClarificationMiddleware
from deerflow.agents.middlewares.forced_research_middleware import (
FORCED_RESEARCH_AGENT_ID,
ForcedResearchMiddleware,
filter_forced_research_tools,
)
from deerflow.agents.middlewares.loop_detection_middleware import LoopDetectionMiddleware
from deerflow.agents.middlewares.memory_middleware import MemoryMiddleware
from deerflow.agents.middlewares.prompt_prefix_middleware import PromptPrefixMiddleware
@@ -373,21 +373,21 @@ def _build_middlewares(
middlewares.append(SkillReviewMiddleware())
# PositionArtifactCapMiddleware — position-roundtable seats (and summary)
# PositionArtifactCapMiddleware — position-roundtable seats (and summary)
# may only emit N outputs write_file calls per user turn. Action-plan skips
# the context flag so it can still write report + JSON.
from deerflow.agents.middlewares.position_artifact_cap_middleware import PositionArtifactCapMiddleware
middlewares.append(PositionArtifactCapMiddleware())
# The built-in forced-research responder has a hard per-turn collection
# gate plus temporary-Python-only sandbox IO. This is runtime enforcement,
# not merely SOUL prompt steering, so weak models cannot answer before a
# successful retrieval/skill-script result exists.
if agent_name == FORCED_RESEARCH_AGENT_ID:
middlewares.append(ForcedResearchMiddleware())
# LoopDetectionMiddleware — detect and break repetitive tool call loops
middlewares.append(PositionArtifactCapMiddleware())
# The built-in forced-research responder has a hard per-turn collection
# gate plus temporary-Python-only sandbox IO. This is runtime enforcement,
# not merely SOUL prompt steering, so weak models cannot answer before a
# successful retrieval/skill-script result exists.
if agent_name == FORCED_RESEARCH_AGENT_ID:
middlewares.append(ForcedResearchMiddleware())
# LoopDetectionMiddleware — detect and break repetitive tool call loops
middlewares.append(LoopDetectionMiddleware())
# Inject custom middlewares before ClarificationMiddleware
@@ -638,20 +638,32 @@ def _make_lead_agent(config: RunnableConfig, *, app_config: AppConfig):
# Default lead agent (unchanged behavior)
is_notebook_mode = bool(cfg.get("notebook_search_space_id"))
notebook_source_ids: list[int] = cfg.get("notebook_source_ids") or []
default_tools = get_available_tools(
default_tools = get_available_tools(
model_name=model_name,
groups=agent_config.tool_groups if agent_config else None,
subagent_enabled=subagent_enabled,
is_scheduled_run=cfg.get("is_scheduled_run", False),
excluded_tools=requested_excluded_tools,
app_config=resolved_app_config,
)
if agent_id == FORCED_RESEARCH_AGENT_ID:
default_tools = filter_forced_research_tools(default_tools)
app_config=resolved_app_config,
)
if agent_id == FORCED_RESEARCH_AGENT_ID:
default_tools = filter_forced_research_tools(default_tools)
if is_notebook_mode:
from deerflow.tools.builtins.notebook_search_tool import notebook_search_tool
default_tools = [notebook_search_tool] + default_tools
# 写作模式首轮(尚无 md 产物):挂深度研究报告工具,报告由管线生成而非
# 模型手工 write_file。续写轮(已有 writing_artifact_path)不挂,保持
# 原有「直接编辑该文件」行为。不受 tool_groups/excluded_tools 过滤——
# 它是写作模式合约的核心交付手段。
if writing_mode and not writing_artifact_path:
from deerflow.tools.builtins.deep_research_report_tool import deep_research_report_tool
default_tools = [*default_tools, deep_research_report_tool]
logger.info(
"Writing mode first report turn: deep_research_report tool mounted for agent=%s",
agent_id,
)
# Custom agents are steered ONLY by their own SOUL.md — no generic
# super-agent system template and no personal memory injection. We branch to