feat(M2.1): AI 语音对话插件骨架 + 模型管理 + HTTP API + config schema 扩展
这是 M2.1(语音数字生命 V1)的后端骨架实现,不含 Web UI / Flutter / 设备部署。 新增文件: - src/plugins/ai/mod.rs: AiPlugin 薄层(持有 ChatPipeline Arc,处理消息系统联动) - src/plugins/ai/backend.rs: AiBackend trait + LocalCliBackend (whisper-cli/llama-cli/piper 子进程) + CloudBackend 占位(V1 返回"暂未支持") - src/plugins/ai/chat.rs: ChatPipeline 对话管线执行器(HTTP 层 spawn_blocking 直接调用) - src/plugins/ai/model_manager.rs: ModelManager 模型资产管理 (清单/下载/切换/删除/配额/档位守门,参照 plugin_repo + version_manager 模式) 修改文件: - src/core/message.rs: 新增 ChatRequest/ChatResponse/AiModelEvent 消息类型 - src/core/config.rs: AppConfig 新增 character 块(角色元信息+人设)+ ai 块(后端配置) 均为 #[serde(default)] 向后兼容旧配置 - src/plugins/mod.rs: 注册 ai 模块 - src/plugins/http/mod.rs: HttpState 新增 ai_pipeline + ai_models 字段及注册方法; HttpPlugin 新增 set_ai_pipeline/set_ai_models 方法 - src/plugins/http/routes.rs: 新增 6 个 AI 相关路由 - POST /api/chat/text (文字对话,Web 端主路径) - POST /api/chat/audio (语音对话,App 主路径) - GET /api/models (模型清单+水位+配额) - POST /api/models/download (下载模型,后台线程执行) - POST /api/models/switch (切换激活模型) - POST /api/models/delete (删除模型,保护当前激活) - src/main.rs: 注册 AiPlugin,连接 pipeline 到 HttpPlugin 技术决策: - 对话管线用 spawn_blocking 而非消息系统,满足 HTTP 同步响应需求 - ChatPipeline 用 Arc<Mutex> 共享,HTTP 和 AiPlugin 共用同一实例 - 互斥用 try_lock,忙时返回 409 而非阻塞 - Spike 结论固化: LLM t=2 锁大核、ctx=1024 限死、Qwen2.5-0.5B 默认档 待完成 (后续提交): - Web 控制端 UI (文字对话 + 角色切换 + 模型管理界面) - Flutter App (角色页/语音页/模型管理页) - 设备端部署 llama.cpp/whisper.cpp/piper 二进制 + 模型下载 - 画面联动 (talk/idle 状态切换) - 测试 注: Windows 开发环境缺 dbus,无法本地 cargo check;待目标机验证。
This commit is contained in:
24
src/main.rs
24
src/main.rs
@@ -5,7 +5,7 @@ use showen_v2::core::service_manager::ServiceManager;
|
||||
#[cfg(not(test))]
|
||||
use showen_v2::core::version_manager::VersionManager;
|
||||
use showen_v2::plugins::{
|
||||
ble::BlePlugin, device::DevicePlugin, http::HttpPlugin, screen::ScreenPlugin,
|
||||
ai::AiPlugin, ble::BlePlugin, device::DevicePlugin, http::HttpPlugin, screen::ScreenPlugin,
|
||||
video::VideoPlugin, wifi::WifiPlugin,
|
||||
};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
@@ -49,7 +49,7 @@ fn main() -> Result<()> {
|
||||
let mut manager = ServiceManager::new(config);
|
||||
|
||||
// 按依赖顺序注册插件
|
||||
// 独立插件:device, screen, wifi, video, ble
|
||||
// 独立插件:device, screen, wifi, video, ble, ai
|
||||
// 依赖插件:http (依赖 video)
|
||||
|
||||
println!("注册插件...");
|
||||
@@ -68,7 +68,25 @@ fn main() -> Result<()> {
|
||||
manager.register(Box::new(BlePlugin::new()));
|
||||
println!(" ✓ BlePlugin");
|
||||
|
||||
manager.register(Box::new(HttpPlugin::new()));
|
||||
// AiPlugin: 需要在注册前创建实例以获取 pipeline 句柄,再注册进 manager
|
||||
// pipeline 会传给 HttpPlugin,建立 HTTP → AI 的直接通道
|
||||
let ai_config = &config.ai;
|
||||
let ai_plugin = AiPlugin::new_default(
|
||||
ai_config.model_store.clone(),
|
||||
ai_config.tools_dir.clone(),
|
||||
ai_config.tmp_dir.clone(),
|
||||
ai_config.context_window,
|
||||
);
|
||||
let ai_pipeline = ai_plugin.pipeline();
|
||||
let ai_models = ai_plugin.models();
|
||||
manager.register(Box::new(ai_plugin));
|
||||
println!(" ✓ AiPlugin");
|
||||
|
||||
let mut http_plugin = HttpPlugin::new();
|
||||
// 注册 AI 句柄到 HttpState(在 http init 之前建立连接)
|
||||
http_plugin.set_ai_pipeline(ai_pipeline);
|
||||
http_plugin.set_ai_models(ai_models);
|
||||
manager.register(Box::new(http_plugin));
|
||||
println!(" ✓ HttpPlugin");
|
||||
|
||||
// 加载动态插件
|
||||
|
||||
Reference in New Issue
Block a user