Files
ai-video-fullstack/backend/services/brains/fastgpt_brain.py
Xin Wang 00270a5c01 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.
2026-07-11 22:26:31 +08:00

69 lines
2.5 KiB
Python

"""FastGPT 大脑:外部托管,context/KB/tools 全在 FastGPT 服务端。
cascade-only(realtime 不兼容外部大脑)。每通电话持有一个稳定 chatId:
greeting(get_chat_init)与后续每轮推理共用它,保证服务端上下文连续。
"""
from __future__ import annotations
from typing import Any
from uuid import uuid4
from fastgpt_client import AsyncChatClient
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.fastgpt_llm import FastGPTLLMService, normalize_base_url
def _extract_welcome(payload: Any) -> str:
"""从 get_chat_init 响应里取开场白(welcomeText),多层兜底。"""
if not isinstance(payload, dict):
return ""
data = payload.get("data") if isinstance(payload.get("data"), dict) else payload
app = data.get("app") if isinstance(data.get("app"), dict) else {}
chat_config = app.get("chatConfig") if isinstance(app.get("chatConfig"), dict) else {}
for value in (
chat_config.get("welcomeText"),
app.get("welcomeText"),
data.get("welcomeText"),
data.get("opener"),
app.get("opener"),
):
if isinstance(value, str) and value.strip():
return value.strip()
return ""
class FastGPTBrain(BaseBrain):
def __init__(self):
self._chat_id = uuid4().hex
spec = BrainSpec(
type="fastgpt",
supported_runtime_modes=frozenset({"pipeline"}),
owns_context=False,
)
async def greeting(self, cfg: AssistantConfig) -> str:
"""优先用 FastGPT 后台配置的开场白;无 app_id 或取不到时回退 cfg.greeting。"""
if not cfg.fastgpt_app_id:
return cfg.greeting
try:
client = AsyncChatClient(
api_key=cfg.fastgpt_api_key,
base_url=normalize_base_url(cfg.fastgpt_api_url),
)
response = await client.get_chat_init(cfg.fastgpt_app_id, self._chat_id)
welcome = _extract_welcome(response.json())
return welcome or cfg.greeting
except Exception as exc: # noqa: BLE001 - 拉取失败不应阻断通话
logger.warning(f"FastGPT get_chat_init 失败,回退 cfg.greeting: {exc}")
return cfg.greeting
def build_llm(self, cfg: AssistantConfig, context: LLMContext) -> FrameProcessor:
return FastGPTLLMService(cfg, chat_id=self._chat_id)