"""「大脑」抽象:把不同助手类型(prompt/workflow/fastgpt/…)在运行时的差异收口。 cascade 管线骨架对所有类型一致(STT → LLM 槽 → TTS),变化的只有: - 谁产出助手文本(LLM 槽里塞什么)——build_llm - 开场白来源(静态 / 外部异步拉取)——greeting - 对话上下文归谁维护——spec.owns_context - 是否支持 realtime——spec.supported_runtime_modes 阶段 1 只抽到「够 fastgpt 用」的程度;workflow 编排仍内联在 pipeline.py, 待阶段 2 再搬进 WorkflowBrain 收口。 """ from __future__ import annotations from dataclasses import dataclass from typing import Protocol, runtime_checkable from models import AssistantConfig from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.frame_processor import FrameProcessor @dataclass(frozen=True) class BrainSpec: """类型元数据。单一来源,供运行时门控与上下文归属决策复用。""" type: str supported_runtime_modes: frozenset[str] # True:由本服务维护 LLMContext(prompt/workflow); # False:上下文/知识库/工具由外部服务端接管(fastgpt/dify),本地不写 context。 owns_context: bool @runtime_checkable class Brain(Protocol): """每通电话 new 一个实例(可持有 chatId / 当前节点等会话状态)。""" spec: BrainSpec async def greeting(self, cfg: AssistantConfig) -> str: """开场白。内部类型通常直接用 cfg.greeting;外部类型异步拉取后端配置。""" ... def build_llm(self, cfg: AssistantConfig, context: LLMContext) -> FrameProcessor: """返回丢进管线 LLM 槽位的帧处理器(标准 LLMService 或外部托管的伪 LLM)。""" ...