deerflow-code/offline-backend-20260512/backend/packages/harness/deerflow/agents/canvas_agent/agent.py
2026-09-07 18:24:55 +08:00

81 lines
3.1 KiB
Python

from __future__ import annotations
import logging
from langchain.agents import create_agent
from langchain_core.runnables import RunnableConfig
from deerflow.agents.canvas_agent.prompt import build_canvas_system_prompt
from deerflow.agents.canvas_agent.tools import update_artifact_tool
from deerflow.agents.middlewares.clarification_middleware import ClarificationMiddleware
from deerflow.agents.middlewares.dangling_tool_call_middleware import DanglingToolCallMiddleware
from deerflow.agents.middlewares.loop_detection_middleware import LoopDetectionMiddleware
from deerflow.agents.middlewares.title_middleware import TitleMiddleware
from deerflow.agents.middlewares.tool_error_handling_middleware import ToolErrorHandlingMiddleware
from deerflow.agents.thread_state import ThreadState
from deerflow.config.app_config import get_app_config
from deerflow.models import create_chat_model
from deerflow.tools.builtins import ask_clarification_tool
logger = logging.getLogger(__name__)
def _get_runtime_config(config: RunnableConfig) -> dict:
cfg = dict(config.get("configurable", {}) or {})
context = config.get("context", {}) or {}
if isinstance(context, dict):
cfg.update(context)
return cfg
def make_canvas_agent(config: RunnableConfig):
"""LangGraph graph factory for canvas mode; signature compatible with LangGraph Server."""
app_config = get_app_config()
cfg = _get_runtime_config(config)
requested_model = cfg.get("model_name") or cfg.get("model")
if requested_model and app_config.get_model_config(requested_model):
model_name = requested_model
else:
if requested_model:
logger.warning("Canvas agent: model '%s' not found; falling back to default.", requested_model)
model_name = app_config.models[0].name if app_config.models else None
if model_name is None:
raise ValueError("No chat models configured. Please add at least one model in config.yaml.")
thinking_enabled = cfg.get("thinking_enabled", False)
model_config = app_config.get_model_config(model_name)
if thinking_enabled and model_config and not model_config.supports_thinking:
thinking_enabled = False
canvas_artifact_title = cfg.get("canvas_artifact_title") or None
canvas_artifact_type = cfg.get("canvas_artifact_type") or None
system_prompt = build_canvas_system_prompt(
artifact_title=canvas_artifact_title,
artifact_type=canvas_artifact_type,
)
logger.info(
"Create CanvasAgent -> model_name: %s, thinking_enabled: %s, artifact_title: %s",
model_name,
thinking_enabled,
canvas_artifact_title,
)
middlewares = [
DanglingToolCallMiddleware(),
ToolErrorHandlingMiddleware(),
TitleMiddleware(app_config=app_config),
LoopDetectionMiddleware(),
ClarificationMiddleware(),
]
return create_agent(
model=create_chat_model(name=model_name, thinking_enabled=thinking_enabled, app_config=app_config),
tools=[update_artifact_tool, ask_clarification_tool],
middleware=middlewares,
system_prompt=system_prompt,
state_schema=ThreadState,
)