跨 macOS / Windows 的电子桌面陪伴宠物:透明无边框置顶窗口里住着一只帧动画胖鸟,会随机游走、被拖拽拎起、被点击摸头,久了不理会困倦趴下。前端 React + TypeScript 约 3900 行,Rust 薄壳约 300 行,21 个测试文件,安装包控制在 15MB 以内。
项目特点
- BYOK 大模型对话:OpenAI 兼容协议,预设 OpenAI / DeepSeek / 通义千问 / 智谱 / Claude 端点,SSE 流式输出;API Key 存系统钥匙串。
- 长期记忆:每轮对话后异步调用 LLM 抽取用户事实写入 SQLite,下次对话时连同对话摘要一起注入 prompt——它真的记得你上次说过的事。
- 三轴情绪引擎:心情 / 好感度 / 精力三个数值同时驱动动画状态机与 system prompt 的语气指令,情绪不止影响表情,也影响说话方式。
- 主动关心系统:早晨问候、久坐提醒(Rust 侧读系统 idle 时间)、深夜关怀、长时间未互动撒娇;LLM 不可用时降级为本地文案,纯桌宠模式完整可用。
- 架构分层:托盘、单实例、双平台 idle 检测(macOS core_graphics / Windows device_query)、钥匙串等系统能力全部下沉 Rust 薄壳,业务逻辑留在 TypeScript 保证迭代速度。
技术难点
透明窗口的点击穿透。 桌宠窗口铺满全屏,但鼠标点在宠物和气泡之外的区域必须穿透到下层应用。方案是前端上报可交互 hit-rect,Rust 线程 100ms 轮询全局光标位置,光标落在交互区外时对整个窗口开启 ignore_cursor_events——还要处理 HiDPI 下物理像素与逻辑坐标的换算。
WebView 的 CORS 与流式。 WebView 直接请求 LLM API 会被 CORS 拦住。所有 LLM 请求强制走 tauri-plugin-http 绕开 WebView 网络栈,流式响应经 Tauri Channel 逐字推回前端渲染,保持打字机体验。
情绪系统的可测试性。 情绪引擎做成纯函数模块(事件进、数值变更出),动画状态机和 prompt 语气都是三轴数值的下游投影,全链路可单测——「性格」因此是可以回归测试的代码,而不是散落在各处的魔法数。