桌面伴侣
桌面伴侣 / Companion:产品功能。伴侣浮层(companion overlay):Portal 透明 VRM 窗(
embedded-overlay)。Outpost(前哨):overlay 内remote_tools.attach角色。Target shell: Tauri(见.agent/rules/tauri-shell.md)。Not managed viaconfig.yaml;禁止再打独立 Node sidecar。
The content pack (React + VRM) is embedded by the desktop Tauri shell
(src/portal/app/tauri). Packaged overlay loads from frontendDist
ui/companion/ via WebviewUrl::App (same custom protocol as the main
window — not file:// resources). The overlay connects with Habitat
RPC, calls remote_tools.attach, and exposes local tools (bubble,
play_slot) to the Agent. Product modules such as Chat use Habitat RPC only
(no attach).
FreeAnima Portal (src/portal/app/tauri)├── Tauri (Rust) — tray / multi-window + prefs / IPC│ ├── companion overlay — work-area fullscreen transparent; VRM stage + remote_tools.attach│ ├── companion settings — settings in main window (Habitat RPC + asset HTTP)│ ├── chat — Chat SPA (Habitat RPC, no remote_tools.attach)│ └── habitat — Habitat WebView (Habitat RPC REST)└── Renderer — portalShell; overlay owns attach + tool runtime ↕ Habitat RPC (+ remote_tools.attach in overlay only) anima service Habitat (companion_profile SSOT + assets + FBX→VRMA)Habitat vs local boundary
Section titled “Habitat vs local boundary”| Layer | Location | Responsibility |
|---|---|---|
| Habitat SSOT | src/features/companion/ | companion_profile entity (behavior, slots, library meta); VRM/VRMA files under ~/.anima/companion/ on Habitat host; FBX→VRMA conversion; Settings read/write via Habitat RPC |
| Settings UI | Desktop Settings → Companion | Habitat RPC(getTypedHabitatClient:call / multipart callRaw;companion.config.*、model/motion CRUD、asset.get) |
| Companion host | overlay SPA (spa/) | remote_tools.attach, tool execution, local runtime (bubble/play); optional thin HTTP for static assets + companion.sync.pull cache |
| Tauri host | src/portal/app/tauri/ | Transparent window, click-through, tray, show/hide + FS / prefs IPC |
Management is in Settings only — Habitat has no companion admin page.
On host start: Habitat config wins; ~/.anima/companion/config.json on the
desktop is an offline cache. Legacy local data is migrated once to
Habitat (companion.migrate.fromLocal or HTTP upload). Multiple desktops
share the same model/motion library via Habitat.
Settings ──Habitat RPC/HTTP──► features/companion (Habitat)Static ◄──sync.pull────► Habitat ──► local cache (VRM/VRMA)Overlay ──remote_tools.attach──► Habitat (bubble / play_slot 本地执行)Tauri ◄──IPC──────────► Settings (show/hide, connection status)Agent ──Habitat RPC tool.call─► OverlayThe content pack lives in
src/features/companion/ (ui/spa/ +
server/ + shared/). Habitat domain logic:
src/features/companion/.
| Chat / other product modules | Companion | |
|---|---|---|
| UI | Browser / shell Web UI | Native transparent companion window + settings |
| Deployment | Bundled in shell | Dynamic attach when Habitat token is configured |
| Protocol | Habitat RPC only (no attach) | Habitat RPC + remote_tools.attach in overlay |
| Runtime | — | Overlay-local tool runtime(browser-dev 同路径) |
- VRM 形象渲染(Three.js +
@pixiv/three-vrm);VRM 1.0 与 0.x 自动朝向校正 - 动作槽位:五个槽位 —
idle、rest、walk、climb、in_place;每槽绑定 0..n 个 VRMA 片段;按 id 或随机播放;空槽 = 无动画 - Speech bubble: one-way text queue; user click advances; no
auto-dismiss; pushed by Habitat Agent via companion
bubbletool - Transparent always-on-top work-area fullscreen overlay; fullscreen WebGL canvas; character placed by in-window screen coordinates (footprint 160×260 for standing scale / patrol margins); avatar/bubble clickable, empty area click-through
- Local interaction: drag moves the character screen position (not the
OS window); click body to play random motion from
in_placeslot - 巡逻(设置 → 行为标签页):空闲巡逻、双击巡逻、角落暂停、巡逻速度、启动时回到起点等
- 系统托盘:显示/隐藏伴侣、设置…(打开设置窗口)、退出
- 设置标签页:常规 / 行为 / 模型 / 动作槽位 / 动作库
Agent tools (host registration)
Section titled “Agent tools (host registration)”| 工具 | 参数 | 说明 |
|---|---|---|
bubble | text: string | 在语音气泡中排队文本 |
play_slot | slot: string;motion_id?: string | 播放动作槽位;motion_id 可选 |
周期性内容(如定时笑话)在 anima service / 定时任务 中配置;Agent 调用 bubble。伴侣无内置定时器。
Settings → Companion client section shows instance id and remote tools connected(overlay 上报 / ShellApi;无 token 时跳过 attach)。
The repo does not bundle .vrm / .vrma files. Habitat is the
SSOT: companion_profile entity in PostgreSQL plus files on the Habitat
host at ~/.anima/companion/models/ and motions/. Each desktop keeps a
local cache synced on host start (companion.sync.pull).
VRM 模型
Section titled “VRM 模型”Settings → Models tab: list, import, delete, rename, switch current
model. Upload goes to Habitat (POST /rpc/v1/companion/model/upload); host
downloads missing files for overlay rendering.
During development, files in src/features/companion/public/models/ serve
as fallback.
VRMA 库与槽位
Section titled “VRMA 库与槽位”Settings → Motion library tab: import VRMA, FBX, or ZIP (FBX is converted on Habitat, not on desktop). Motion slots tab assigns motions per slot. Preview supports mouse drag to rotate view.
Unbound slots play no animation; patrol still moves the window; walk/climb VRMA play only when bound.
FBX import
Section titled “FBX import”FBX→VRMA runs on the Habitat host (anima service). Desktop installers
no longer bundle fbx2vrma-converter or FBX2glTF. On the Habitat machine
run just misc setup-fbx if FBX conversion is needed.
Browser /dev companion host
Section titled “Browser /dev companion host”bun src/features/companion/dev.tsUses an in-process HTTP server; runtime events use localhost WebSocket
(/api/runtime/ws).
Desktop (Tauri Portal)
Section titled “Desktop (Tauri Portal)”The Portal companion overlay WebView hosts companion UI and
remote_tools.attach(embedMode: embedded-overlay;禁止 Node sidecar)。Window
/ IPC / FS come from Tauri commands. See
.agent/rules/tauri-shell.md.
Settings storage
Section titled “Settings storage”Companion config has two storage layers:
| Layer | Content | Access |
|---|---|---|
Habitat PG (companion_profile) | Behavior, models, motion library, slots | Settings → Habitat → Companion via Habitat RPC / HTTP |
| Local device | Window visibility (companion-shell scope), Habitat RPC runtime status (read-only) | Settings → local → Companion |
Local ~/.anima/companion/config.json is only a habitat-sync cache; the
settings UI does not read/write it directly.
After Habitat profile changes, the local cache syncs via
companion.sync.pull; the overlay refreshes through emitConfigChanged.
See also: Habitat RPC, architecture companion section.