ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AIRI 十月 DevLog 技术复盘:Tauri 迁往 Electron、Control Island 与 Eventa 事件驱动架构

AIRI 十月 DevLog 技术复盘:Tauri 迁往 Electron、Control Island 与 Eventa 事件驱动架构 AIRI 十月 DevLog 技术复盘Tauri 迁往 Electron、Control Island 与 Eventa 事件驱动架构【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi本篇技术指南基于 AIRI 项目的官方开发日志DevLog 2025.10.20展开逐一复盘本项目从 Tauri 到 Electron 的完整迁移动因与落地成果Control Island、字幕浮层、Linux/macOS 适配并深入解析新 Live2D 模型、Three.js MMD 渲染、Velin 提示词框架、Eventa 事件驱动 IPC/RPC 以及纯 Rust TTS 等前沿探索。读完本文你将掌握 AIRI 桌面端apps/stage-tamagotchi的窗口架构、事件契约设计思路与 3D/2D 模型渲染选型方案可直接对照源码继续深入。从 Tauri 到 Electron一次知难而退的技术栈迁移AIRI 曾是 Tauri 的早期用户。自 2025 年 3 月采用以来团队一直欣赏 Tauri 的插件设计与 Rust crate 封装生态并在 6 月发布了 v0.7.2。但为了交付社区呼声最高的实时语音聊天能力团队在 Tauri 的 WebKit 渲染内核、Web Audio API 与 DevTools 的组合上挣扎了整整 3 个月直到 9 月最终在国庆假期期间彻底切换到 Electron。迁移的决策动因日志中坦诚地记录了这次迁移的核心矛盾WebKit 的音频栈难以承载 AIRI 实时语音聊天所需的低延迟、高精度音频处理Web Audio API 在 Tauri 内核下表现得别扭DevTools 调试体验无法满足桌面端复杂窗口与多进程场景的排障需求3 个月的反复修补最终被证明性价比不足Electron 成熟的窗口、进程与平台 API 成为更务实的选项。迁移后的架构落地仓库现状印证当前仓库中AIRI 桌面端位于 apps/stage-tamagotchi其目录结构完整呈现了迁移后的 Electron 工程形态src/mainElectron 主进程负责窗口管理、服务编排MCP、HTTP server、插件宿主、自动更新等src/preload预加载脚本承载事件桥接src/rendererVue 渲染层包含舞台、Control Island、字幕浮层等页面electron.vite.config.ts 与 electron-builder.config.ts构建与打包配置ai.moeru.airi.desktop桌面入口元数据。迁移并非简单换壳而是叠加了多项新能力Linux 支持、Control Island控制岛浮层以及macOS 全屏模式下依然可以悬浮在界面之上。Linux 适配在源码中有非常具体的证据。在 主进程入口 中可以看到平台相关开关if (isLinux) { app.commandLine.appendSwitch(enable-features, SharedArrayBuffer) app.commandLine.appendSwitch(enable-unsafe-webgpu) app.commandLine.appendSwitch(enable-features, Vulkan) if (env.XDG_SESSION_TYPE wayland) { app.commandLine.appendSwitch(enable-features, GlobalShortcutsPortal) app.commandLine.appendSwitch(enable-features, UseOzonePlatform) app.commandLine.appendSwitch(enable-features, WaylandWindowDecorations) } }这段代码解决了两个 Linux 专属问题一是navigator.gpu.requestAdapter()在 Linux 上失败必须通过命令行开关启用 WebGPU/Vulkan 才能快速处理着色器二是在 Wayland 会话下需要UseOzonePlatform、WaylandWindowDecorations与GlobalShortcutsPortal才能正常显示窗口与注册全局快捷键对应 issue #757。这些细节说明迁移后的版本是为多平台而写而非简单移植。字幕浮层Neuro-sama 式可见的 AI 输出日志提到迁移完成后终于把字幕浮层跑通了现在能像 Neuro-sama 一样看到 AI 在输出什么。这条能力在仓库中有完整的实现渲染页面位于 renderer/pages/caption.vue通过BroadcastChannel频道名airi-caption-overlay接收caption-speaker与caption-assistant两类字幕事件字幕项默认 10 秒过期CAPTION_TEXT_EXPIRY_MS 10_000窗口管理位于 main/windows/caption/index.ts字幕窗口使用type: panel、透明无边框配置并执行window.setAlwaysOnTop(true, screen-saver, 2)与window.setVisibleOnAllWorkspaces(true)macOS 下还调用setWindowButtonVisibility(false)隐藏窗口按钮是否跟随主窗口由事件契约captionGetIsFollowingWindowinvoke与captionIsFollowingWindowChangedevent双向同步定义在 shared/eventa/index.ts。Control Island桌面伴侣的遥控器迁移 Electron 后新增的Control Island是日志中最亮眼的交互创新——它像 iPhone 上的灵动岛一样悬浮在桌面端窗口边缘随时可展开为一块完整的控制面板。从源码看它的功能全貌控制岛主体实现在 renderer/components/stage-islands/controls-island/index.vue。展开面板expanded内包含 8 个动作按钮全部带埋点v-track-button按钮动作底层事件契约设置打开设置窗口并跳转路由electronOpenSettings({ route })切换 Profile弹出角色配置选择器ControlsIslandProfilePicker刷新窗口重载当前渲染页面window.location.reload()居中主窗口将主窗口移回屏幕中心electronCenterMainWindow明暗主题切换 dark/light 模式useTheme().toggleDark()置顶/取消置顶切换窗口 always-on-topelectronWindowSetAlwaysOnTop悬停淡出鼠标穿透点击穿透模式ControlsIslandFadeOnHover退出应用请求主进程退出electronAppQuit常驻主控件区始终可见则包括展开/折叠切换、打开聊天、听力/麦克风控制ControlsIslandHearingConfig与IndicatorMicVolume、停止说话controls-island-stop-speaking.vue以及拖拽窗口按钮。交互细节防误触与自动收拢控制岛在交互上有几个值得借鉴的细节鼠标离开自动收拢通过useElectronMouseInElement(islandElement)检测光标是否移出再经refDebounced(..., 1500)防抖 1.5 秒后收拢面板同时用useIntervalFn每 1.5 秒兜底复查阻塞覆盖层防误收blockingOverlays集合记录听力配置Profile 选择器等打开中的弹层只要存在阻塞项鼠标离开也不会自动收拢拖拽的平台差异源码注释明确指出 Electron 的startDraggingWindow在 Linux 上不可用因此只有非 Linux 平台才通过defineInvoke注册该事件Linux 上改用cursor-movedrag-regionclass 方案位置与动画放置逻辑抽离在 use-controls-island-placement.ts支持四角吸附top-left/top-right/bottom-left/bottom-right、进出场动效entering/leaving/idle相位与图标尺寸设置large/small/autoauto目前固定按 large 处理。这些交互都有配套测试如 controls-island-root.test.ts、controls-island-stop-speaking.test.ts、controls-island-auth-button.test.ts印证了该模块是经过工程化打磨的核心交互组件。新 Live2D 模型与官方团队合作的视觉升级日志中眼尖的朋友可能已经发现的彩蛋是 AIRI 的角色模型完成了更新。这个新模型由两位关键人物参与改进一位与 Neuro-sama 官方团队合作过的画师以及一位技术极强的建模专家新模型的动态表情也丰富了许多。日志调侃式地表示也许拿到更多赞助就会开源原模型尚未直接放入开源仓库并附上了 演示视频。对于想要自行更换模型的开发者AIRI 在 packages/stage-ui-live2d 提供了完整的 Live2D 舞台渲染支持与stage-ui-threeVRM、stage-ui-mmdMMD、stage-ui-spineSpine共同构成多模型格式渲染矩阵。Three.js MMD 支持让存量 MMD 模型回归舞台日志指出一个现实问题手头能找到的模型未必都是 Live2D/VRM数量最多、质量最好的存量模型其实是 MMDMikuMikuDance模型。虽然 AIRI 用 Three.js 做 3D 渲染但 Three.js 官方生态中已经没有可用的 MMD 实现。得益于 kwaa 的工作Moeru AI 维护了一个专门的 MMD 仓库AIRI 在此基础上构建了自己的 MMD 渲染包。stage-ui-mmd 包的能力清单仓库内的 packages/stage-ui-mmd/README.md 详细说明了该包的定位在 AIRI 舞台上渲染 PMX/PMD 模型并播放 VMD/VPD 动作达到与 Live2D、VRM 渲染器对等的功能模型加载支持.pmx/.pmd可从打包 ZIP模型 贴图或裸模型 URL 加载物理系统基于 BulletAmmo.js实现头发、裙摆与自定义骨骼的刚体 6-DOF 弹簧关节物理运行时可开关IK 与继承骨骼CCD 求解器 IK 与 append-bonegrant传播兼容标准与非标骨骼动作管理导入 VMD 动作剪辑持久化到 IndexedDB 并跨窗口同步、设为循环待机、一次性预览、删除以及将 AIRI 情感映射到手势动作口型同步基于共享 wLipSync profile将音素映射到规范化的あいうえお口型 morph并支持非标模型的逐槽位 morph 重映射情感表情通过 morph 交叉淡入淡出实现注视模式摄像头/光标/关闭三种模式 空闲扫视 程序化眨眼场景设置模型变换、相机 FOV、环境光 方向光、自发光、渲染倍率、物理重力、逐材质透明度——全部实时生效、持久化并跨窗口同步。物理运行时moeru/three-mmd-physics-ammo采用懒加载Ammo WASM 只在真正的 MMD 模型挂载后才初始化避免舞台启动时的额外开销。使用方式stage-ui-mmd暴露与其他渲染器一致的场景契约由 packages/stage-ui 的Stage.vue在模型解析为mmd渲染器时自动接入MMDScene v-model:statestate :model-srcmodelUrl :cursor-positioncursorPosition :current-audio-sourceaudioSource :enable-orbit-controlstrue erroronError /组件还暴露canvasElement()、captureFrame()、setEmotion(name, intensity)、listMorphs()与listMotions()等方法运行时配置物理/IK/grant 开关、注视追踪、缩放、morph 覆盖、情感→动作映射则存放在useMMDPinia store 中通过模型设置面板编辑。日志中如果你也感兴趣欢迎一起来维护的号召对应的是 Moeru AI 旗下该 MMD 相关仓库的开放维护策略。Velin用 Vue 写提示词日志回顾了 5 月分享的提示词库项目得益于 RainbowBird 的努力与捐赠Velin 已正式并入 Moeru AI 组织。它的核心理念是一句口号——You can write prompts with Vue。AIRI 的提示词几乎全部由 Velin 驱动并且跨平台能力无需担心Velin 在 Node.js 环境同样运行良好这意味着同一套用 Vue 组件描述提示词的写法既能服务浏览器场景也能服务桌面端与后端 Node 进程。这对 AIRI 这类同时拥有 Web / macOS / Windows / Linux 多端形态的项目而言保证了提示词定义与渲染逻辑的高度复用。Eventa事件驱动的 IPC/RPC 框架日志介绍 Eventa 时引用了一句口号——Events are all you need。它源自一个痛点AIRI 的本地推理只能跑在 Web Workers / worker_threads 中这些线程之间靠事件通信Electron 的 IPC 本质也如此但团队认为不够优雅。RainbowBird 将这套思想落地为Eventa——基于事件的 IPC/RPC 实现库并正式并入 Moeru AI。仓库中的两级证据第一级通用契约包proj-airi/electron-eventapackages/electron-eventa。它是 AIRI 各应用间共享的 Electron IPC 契约定义分两个入口导出proj-airi/electron-eventa核心契约按 Electron 模块组织——appisMacOS/isWindows/isLinux/quit、windowbounds 变更事件、start-loop-get-bounds、get/setBounds、setIgnoreMouseEvents、setVibrancy、setBackgroundMaterial、resize、close、screen光标屏幕坐标事件、getAllDisplays/getPrimaryDisplay、DIP 与物理坐标互转、powerMonitor、system-preferencesproj-airi/electron-eventa/electron-updater自动更新契约与状态类型。以 window.ts 为例契约的声明方式非常直观export const bounds defineEventaRectangle(eventa:event:electron:window:bounds) export const startLoopGetBounds defineInvokeEventa(eventa:event:electron:window:start-loop-get-bounds) const getBounds defineInvokeEventaReturnTypeBrowserWindow[getBounds](eventa:invoke:electron:window:get-bounds) const setBounds defineInvokeEventavoid, ParametersBrowserWindow[setBounds](eventa:invoke:electron:window:set-bounds) const resize defineInvokeEventavoid, { deltaX: number, deltaY: number, direction: ResizeDirection }(eventa:invoke:electron:window:resize)事件名采用eventa:event:模块:能力与eventa:invoke:模块:能力的统一命名空间ResizeDirection支持n/s/e/w/ne/nw/se/sw八个拖拽方向。第二级应用级契约src/shared/eventaapps/stage-tamagotchi/src/shared/eventa/index.ts。这是整个桌面端进程间通信的总清单覆盖窗口生命周期electronWindowLifecycleChanged、全局快捷键electronShortcutRegister/Unregister/Triggered、MCP stdio 服务器管理electronMcpListTools、electronMcpCallTool、electronMcpTestServer等、插件宿主状态、Godot 舞台旁路进程electronGodotStageStart/Stop/ApplySceneInput、小部件窗口widgetsAdd/Update/Remove、认证OIDC PKCE 登录回调、i18n 与自动更新通道latest/stable/alpha/beta/nightly/canary等。主进程侧则通过moeru/eventa/adapters/electron/main的createContext统一注册见 apps/stage-tamagotchi/src/main/index.ts渲染层再经由proj-airi/electron-vueusepackages/electron-vueuse的useElectronEventaInvoke/useElectronEventaContext消费。这种声明即契约、跨进程类型安全的模式正是 Eventa 相对原生ipcMain.handle更优雅的地方。一个工程细节值得一提桌面叠加层desktop overlay在加载渲染页面之前必须先注册 eventa RPC否则onMounted触发的首次轮询 invoke 将永远悬挂导致后续轮询全部卡死注释记录在 main/windows/desktop-overlay/index.ts——这是事件驱动架构下典型的时序陷阱也印证了Events are all you need背后需要严谨的注册顺序管理。项目状态50 仓库与多语言技术栈日志披露Moeru AI 与 Project AIRI 已成长为大型组织拥有超过 50 个原创仓库覆盖机器学习、数据处理、前端、后端等方向技术栈横跨TypeScript / Python / Rust / Go等语言全部仓库累计关注者超过 800 人。对一年前刚起步的团队而言这被日志作者称为当时完全无法想象的结果。从本仓库的目录结构看这一描述是可验证的——packages 下数十个独立发布的前端/渲染/服务包、apps 下多端应用、engines 下的 Godot 渲染引擎、integrations 下的 Discord/Telegram/Minecraft 等生态接入共同构成了一个名副其实的自托管 AI 伴侣技术矩阵。纯 Rust TTS摆脱 Python 环境的本地推理日志以小预告的形式分享了最新合作与 kwaa 联手将知名 TTS 模型chatterbox 移植为纯 Rust 实现目标是再也不用担心麻烦的 Python 环境配置。其亮点包括推理性能在 4080S 上单次推理约5 秒架构保真基本 1:1 复刻了 Python 版模型架构长期目标将其构建为超级精简的本地 TTS 推理引擎并叠加其他 SOTA TTS 模型的能力。对 AIRI 这类自托管、数据自持的桌面伴侣而言纯 Rust 的 TTS 意味着更轻的分发体积、更少的运行时依赖与更可控的延迟——这与项目self-hosted, you-owned的核心理念一脉相承。结语与后续预告这篇 DevLog 以one more thing的方式串起了 AIRI 从渲染内核到模型生态、从进程通信到本地推理的多条技术主线Electron 迁移换来了稳定而丰富的桌面能力控制岛、字幕浮层、Linux/全屏适配MMD 渲染补全了存量模型资产Eventa 统一了跨进程通信Rust TTS 则瞄准了极简本地推理。日志最后预告后续将持续更新重点介绍团队在VLAVision-Language-Action/VLMVision-Language Model游戏操控方向上的探索思路与阶段性成果——对于想了解AI 伴侣如何真正看懂并操作游戏的读者这是一个值得持续关注的演进方向。【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表