配置模块
src/lab/config_manager/ 负责 TOML 配置加载、Pydantic 校验、默认值补全、自动写回。
它的定位很朴素:让 lab.toml 永远是一个可直接读取、结构完整、类型可靠的配置对象,而不是一堆随手拼出来的字典。
核心设计
Pydantic 驱动
所有配置都由 Pydantic BaseModel 管理,这带来三件事:
- 类型安全:字段类型自动校验
- 默认值集中:默认配置直接写在模型里
- 序列化稳定:
model_dump()后可以直接回写 TOML
from lab.config_manager import load_settings_file, XnneHangLabSettings
settings = load_settings_file("lab.toml", XnneHangLabSettings)加载流程
load_settings_file() 的工作顺序固定:
- 搜索配置文件位置
- 用
tomllib读取 TOML - 交给 Pydantic 做校验和默认值补全
- 用
tomli_w写回完整配置
这样设计的原因,是让“缺字段”变成可恢复状态,而不是把运行期异常直接甩给用户。
主配置类
XnneHangLabSettings 是整个项目的配置入口。当前结构如下:
class XnneHangLabSettings(BaseModel):
conf_version: str = "v1.6.5"
asr: ASRSettings
webui: AudioRecognizeSettings
agent: AgentSettings
local_embedding: LocalEmbeddingSetting
package: PackagesSettings
root: RootAbsDir
server: ServerSettings
memory_bench: MemoryBenchSettings这里的重点不是“字段多”,而是每个子模块都拥有自己的独立模型。这样 UI、服务端、Agent 初始化都能按模块读取,不需要到处手写键名。
Agent 配置分层
AgentSettings 当前的关键字段是:
class AgentSettings(BaseModel):
chat_model: ChatModelSetting
vision_model: VisionModelSetting
enable_tool: bool = True
prompts: PromptSettings
llm: LLMSettings
translate_provider: TranslateProvider = "llm"
translate: TranslateSettings
user_lang: Literal["ZH", "EN", "JA"] = "ZH"
speaker_lang: Literal["ZH", "EN", "JA"] = "ZH"
tts: TTSSettings
faster_first_response: bool = False
max_vision_concurrency: int = 4
require_detailed: bool = True
structured_history_full_turns: int = 5
segment_method: Literal["regex", "pysbd"] = "pysbd"
interrupt_method: Literal["system", "user"] = "user"
memory_agent_profile: str = "profiles/baoqiao.toml"
memory_chat_profile: str = "profiles/congyin.toml"其中 LLMSettings 现在已经改成“provider 列表 + 名称引用”的结构,而不是把 provider 名字硬编码进字段层级:
class LLMProviderSetting(BaseModel):
name: str
llm_api_key: str = ""
llm_base_url: str = ""
api_format: Literal["chat_completion"] = "chat_completion"
class LLMSettings(BaseModel):
providers: list[LLMProviderSetting] = []chat_model.llm_provider 和 vision_model.llm_provider 会在校验阶段检查:如果填写了 provider 名称,那么它必须能在 agent.llm.providers 中找到同名条目。
一个重要变化
现在的配置分层已经很明确:
lab.toml负责全局运行时配置(模型 provider、端口、ASR、包开关等)profiles/*.toml负责角色 / 场景配置(persona、format、plugins、character、TTS 情绪映射)
因此,以下内容不再属于 lab.toml:
- persona / format prompt
- 角色身份与前端展示字段
- Live2D 模型名
- TTS 文本预处理
- TTS 角色名与 emotion → ref_audio 映射
这些都在 Profile 系统里承接。
另外,[agent.llm] 还有一个兼容层:旧版 [agent.llm.openai] 这类结构仍然能被读取,但会在模型校验后迁移成统一的 [[agent.llm.providers]] 结构。这也是文档里应该优先展示列表写法的原因。
与 Profile 系统的衔接
运行时 ServiceContext 会:
- 从
lab.toml读取memory_agent_profile - 加载对应
profiles/*.toml - 将
[character]转换为内部CharacterSettings - 将
[character.tts_preprocessor]转成tts_preprocessor_config - 将
[character.tts]转成tts_config
也就是说,TTS 情绪联动现在不是硬编码,而是 profile 驱动。
详见:Profile 系统。
Package 开关
[package]
sherpa_asr = false
qwen_asr = false
llm_translate = false
local_embedding = false
gsv_lite = false
genie_tts = true
qwen_tts = false
memory_bench = false
to_do_list = true
yutto_uiya = truesherpa_asr 和 qwen_asr 可同时开启,各自注册独立路由,互不干扰。
配置文件位置
默认搜索顺序:
{当前目录}/config/lab.toml{XDG_CONFIG_HOME}/lab.toml或 Windows 的~/AppData/lab.toml
如果都不存在,load_settings_file() 会在 config/ 下创建默认配置。
与其他模块的关系
service_context.py会读取配置并初始化 Agent 与服务上下文server.py会根据[package]开关决定加载哪些路由AgentFactory会读取[agent],再继续进入 Profile / Plugin / ToolManager 流程Profile负责角色化配置;config_manager不再直接承载这些角色字段