跳转到内容

桌面伴侣

桌面伴侣 / Companion:产品功能。伴侣浮层(companion overlay):Portal 透明 VRM 窗(embedded-overlay)。Outpost(前哨):overlay 内 remote_tools.attach 角色。Target shell: Tauri(见 .agent/rules/tauri-shell.md)。Not managed via config.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)
LayerLocationResponsibility
Habitat SSOTsrc/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 UIDesktop Settings → CompanionHabitat RPC(getTypedHabitatClientcall / multipart callRawcompanion.config.*、model/motion CRUD、asset.get)
Companion hostoverlay SPA (spa/)remote_tools.attach, tool execution, local runtime (bubble/play); optional thin HTTP for static assets + companion.sync.pull cache
Tauri hostsrc/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─► Overlay

The content pack lives in src/features/companion/ (ui/spa/ + server/ + shared/). Habitat domain logic: src/features/companion/.

Chat / other product modulesCompanion
UIBrowser / shell Web UINative transparent companion window + settings
DeploymentBundled in shellDynamic attach when Habitat token is configured
ProtocolHabitat RPC only (no attach)Habitat RPC + remote_tools.attach in overlay
RuntimeOverlay-local tool runtime(browser-dev 同路径)
  • VRM 形象渲染(Three.js + @pixiv/three-vrm);VRM 1.0 与 0.x 自动朝向校正
  • 动作槽位:五个槽位 — idlerestwalkclimbin_place;每槽绑定 0..n 个 VRMA 片段;按 id 或随机播放;空槽 = 无动画
  • Speech bubble: one-way text queue; user click advances; no auto-dismiss; pushed by Habitat Agent via companion bubble tool
  • 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_place slot
  • 巡逻(设置 → 行为标签页):空闲巡逻、双击巡逻、角落暂停、巡逻速度、启动时回到起点等
  • 系统托盘:显示/隐藏伴侣、设置…(打开设置窗口)、退出
  • 设置标签页:常规 / 行为 / 模型 / 动作槽位 / 动作库
工具参数说明
bubbletext: string在语音气泡中排队文本
play_slotslot: stringmotion_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).

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.

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→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.

Terminal window
bun src/features/companion/dev.ts

Uses an in-process HTTP server; runtime events use localhost WebSocket (/api/runtime/ws).

The Portal companion overlay WebView hosts companion UI and remote_tools.attachembedMode: embedded-overlay;禁止 Node sidecar)。Window / IPC / FS come from Tauri commands. See .agent/rules/tauri-shell.md.

Companion config has two storage layers:

LayerContentAccess
Habitat PG (companion_profile)Behavior, models, motion library, slotsSettings → Habitat → Companion via Habitat RPC / HTTP
Local deviceWindow 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.