Add Dify integration and enhance workflow node specifications
- Introduce new fields `dify_api_url` and `dify_api_key` in `AssistantConfig` for Dify API integration. - Update `requirements.txt` to include `dify-client-python` for Dify SDK support. - Modify `config_resolver` to handle Dify connection information. - Add a new `globalNode` type in workflow specifications to provide unified settings across workflows. - Enhance node specifications with additional constraints and default values for better configuration management. - Update frontend components to support the new `globalNode` type and its properties, improving workflow editor functionality.
This commit is contained in:
61
backend/services/brains/dify_brain.py
Normal file
61
backend/services/brains/dify_brain.py
Normal file
@@ -0,0 +1,61 @@
|
||||
"""Dify-hosted brain: prompt, workflow, tools, and context live in Dify."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
from dify_client import AsyncClient
|
||||
from loguru import logger
|
||||
from models import AssistantConfig
|
||||
from pipecat.processors.aggregators.llm_context import LLMContext
|
||||
from pipecat.processors.frame_processor import FrameProcessor
|
||||
|
||||
from services.brains.base import BaseBrain, BrainSpec
|
||||
from services.brains.dify_llm import DifyLLMService, normalize_api_base
|
||||
|
||||
|
||||
class DifyBrain(BaseBrain):
|
||||
spec = BrainSpec(
|
||||
type="dify",
|
||||
supported_runtime_modes=frozenset({"pipeline"}),
|
||||
owns_context=False,
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self._user_id = f"ai-video-{uuid4().hex}"
|
||||
self._client: AsyncClient | None = None
|
||||
|
||||
def _get_client(self, cfg: AssistantConfig) -> AsyncClient:
|
||||
if self._client is None:
|
||||
if not cfg.dify_api_key:
|
||||
raise ValueError("缺少 Dify Agent apiKey")
|
||||
self._client = AsyncClient(
|
||||
api_key=cfg.dify_api_key,
|
||||
api_base=normalize_api_base(cfg.dify_api_url),
|
||||
)
|
||||
return self._client
|
||||
|
||||
async def greeting(self, cfg: AssistantConfig) -> str:
|
||||
"""Use Dify's opening statement, with the local greeting as fallback."""
|
||||
try:
|
||||
api_base = normalize_api_base(cfg.dify_api_url)
|
||||
response = await self._get_client(cfg).arequest(
|
||||
f"{api_base}/parameters",
|
||||
"GET",
|
||||
params={"user": self._user_id},
|
||||
timeout=15.0,
|
||||
)
|
||||
opening = str(response.json().get("opening_statement") or "").strip()
|
||||
return opening or cfg.greeting
|
||||
except ValueError:
|
||||
raise
|
||||
except Exception as exc: # noqa: BLE001 - greeting failure should not block a call
|
||||
logger.warning(f"Dify 获取开场白失败,回退 cfg.greeting: {exc}")
|
||||
return cfg.greeting
|
||||
|
||||
def build_llm(self, cfg: AssistantConfig, context: LLMContext) -> FrameProcessor:
|
||||
return DifyLLMService(
|
||||
cfg,
|
||||
client=self._get_client(cfg),
|
||||
user_id=self._user_id,
|
||||
)
|
||||
Reference in New Issue
Block a user