81 lines
3.1 KiB
Python
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,
|
|
)
|