架构
系统级约束与长期设计原则。
Product naming (Habitat / Portal)
Section titled “Product naming (Habitat / Portal)”User-facing product terms (Chinese in
i18n/glossary.md):
| Role | English | Chinese | Meaning |
|---|---|---|---|
| Long-running process / connect target | Habitat | 栖息地 | One process hosts multiple digital lives (agent subjects) and human assets (user); connect / token / restart target |
| External connectors (class) | Portal | 入口 | Class of ways into Habitat; four forms: application / browser / mcp / cli |
| Portal form | — | 入口形态 | Realization kind of a Portal |
| Application-form Portal | Shell | 壳 / 应用形态 | Form application — windowed SPA(desktop / mobile / web)。Not app frame |
| Browser-form Portal | — | 浏览器形态入口 | Form browser — browser extension(MV3);src/portal/extension;not Web Shell |
| MCP-form Portal | MCP | MCP 形态入口 | Form mcp — Habitat /mcp(mcp-server)。Inbound mcp-client is not a Portal |
| CLI-form Portal | CLI | CLI 形态入口 | Form cli — anima CLI;src/portal/cli |
| Remote-tool registrant | Outpost | 前哨 | Unreachable local app that remote_tools.attach (Portal-embedded companion or standalone tool); not a Portal |
| Shell | Shell | 壳 | Application-form Portal(desktop / mobile / web)。Not Habitat; not app frame; not browser Portal |
| app frame | app frame | 应用布局 | SPA chrome in src/client/app-frame (AppFrame); viewport-driven; orthogonal to Shell |
| Admin / inspect UI (legacy Habitat) | Habitat (UI) | 栖息地 | Area under /habitat/*; “Open Habitat” vs “Connect to Habitat” |
| Admin home page | Dashboard | 仪表盘 | /habitat/dashboard only; other Habitat routes keep their own labels |
| Message bridges | Gateway | Gateway | Discord / WeChat — not a Portal |
| Protocol / code identifiers | — | 协议/代码标识 | /rpc/v1、HabitatRPC/1.0、habitat_*、habitat_runtime_config、dev:habitat |
Verbs: connect to Habitat (URL + token); open Habitat (admin UI); reach via a Portal (Shell / browser extension / MCP / CLI).
Code layout: src/portal/{app,extension,cli};MCP-form implementation stays
in src/host/capabilities/mcp-server. See
docs/modules/portal.md.
Estate Body (VM / OS / network under the four-layer model) is the cognitive “what I run on” for a subject — not the Habitat process name.
Habitat configuration (SSOT)
Section titled “Habitat configuration (SSOT)”User copy says Habitat. Storage/RPC identifiers use habitat_* /
HabitatRPC/1.0 / /rpc/v1.
| Layer | Storage | Who reads/writes |
|---|---|---|
| Bootstrap | ~/.anima/config.yaml (database, http, redis) | platform/boot only; install/ops edit YAML |
| Runtime | PostgreSQL habitat_runtime_config | Engine, tools, Shell Habitat settings, Habitat UI config.* |
Naming cleanup
Section titled “Naming cleanup”Legacy hub_* / console protocol aliases and dual-write keys have been
removed; use Habitat identifiers only.
- 记忆体系内部可以分层,但 LLM 只看到一个统一入口
- 记忆编排内建于运行时;LLM 不控制记忆流水线
- 凭证管理是一等系统关切
- Habitat runtime configuration (LLM, compression, integrations) is
persisted in PostgreSQL (
habitat_runtime_config);~/.anima/config.yamlholds bootstrap only (database,http,redis) for cold start — not editable via Shell or Habitat UI API - Habitat may start without LLM configured; first-time setup happens in
Shell Settings → Habitat (persist to PG). Saving runtime config
hot-applies in memory (no Habitat restart). Missing
llmmust not block cold start. - Habitat hosts browser
/web/*whenever Web dist is present (no config switch; runjust pack webfor source deploy). Sourcejust dev habitatskips hosting so Vite serves the UI. - Asset management is a first-class system concern
Bootstrap and runtime are not merged into a single config object (no
AnimaConfig / animaConfigSchema supersets). Types:
bootstrapConfigSchema vs runtimeConfigSchema / Config.data: RuntimeConfig. CLI cold paths connect via internal withPlatformDb and
receive runtime only. Legacy runtime keys in config.yaml are ignored
(optional startup warn).
Runtime config: live vs transferred
Section titled “Runtime config: live vs transferred”| Kind | Sections (examples) | After UI save |
|---|---|---|
| Live | compression, memory, fts, cjk, clarify, browser, firecrawl, models, tts, auto_llm, gateway tool_display | Consumers read Config.data each use; snapshot update is enough |
| Transferred | llm, i18n, embedding, mcp_servers, acp_agents, discord / weixin / gateway platforms, worlds | Snapshot update plus section apply (re-init registries / reconnect / re-bind) |
| Bootstrap | database, http, redis | Edit YAML; process restart required |
| Hard / rare | eventbus (queue already built) | Prefer process restart if changing key_prefix etc. |
- 系统提示词是架构的一部分,而非临时字符串拼接
四层认知模型
Section titled “四层认知模型”数字生命由内而外分层。每一层回答一个不同的核心问题:
┌───────────────────────────────────────────────┐│ ① Consciousness ││ "What am I aware of right now?" ││ The LLM runtime stream — the innermost now. ││ Not persisted; flows and fades. │├───────────────────────────────────────────────┤│ ② Self ││ "Who am I?" ││ └── existence_anchor (nearly immutable) ││ └── self_model (updatable) ││ └── personality_baseline (semi-stable) ││ └── direction ││ └── metacognition ││ └── autobiography_summary (append-only) ││ See [`self-layer.md`](../cognition/self-layer.md) │├───────────────────────────────────────────────┤│ ③ Memory ││ "What do I know / remember?" ││ └── Semantic (incl. `procedural` type) ││ └── Episodic ││ └── Limbic / Imprint ││ See [`memory.md`](../cognition/memory.md) │├───────────────────────────────────────────────┤│ ④ Estate ││ "What do I have / rely on?" ││ ├── Body: VM / OS / network / toolchains ││ │ (Estate cognitive body — not Habitat) ││ ├── Internal assets: notes, projects, code ││ └── External assets: email, accounts, creds││ Credentials: see "Credential System" below │└───────────────────────────────────────────────┘- 自上而下依赖:感知层内容沉淀为自我层;自我层决定什么进入记忆层;记忆层与运行需求驱动资源层需求。
- 自我与感知:感知是流动的觉察;自我是从中沉淀下来的稳定「我」。
- 自我与记忆:自我回答「我是谁」;记忆回答「我知道什么」。二者同级、性质不同。
- 资源层在最外层——不是「我是谁」,而是「我拥有什么、依托什么运行」。身体与资产在此交汇,作为边界的延伸。
统一实体存储(v0.8)
Section titled “统一实体存储(v0.8)”Structured business data (tasks, notes, email accounts/messages, future
memory migrations) converges on a single entities PostgreSQL table
with component tags (task_list, task_item, email_account, …). Self
layer self_blocks stays physically
separate. See entity-model.md(remove / deleteComponent
/ deleteEntity 软删与回收站;Shell Entity 模块见
../modules/entity.md)。
Shell UI /tasks and /email are primary module entries
(entity-backed); legacy Habitat email route removed.
Anima URI (Shell locator)
Section titled “Anima URI (Shell locator)”Entity deep links / overlay / clipboard use Anima URI
(anima:{id}?component=…&present=…). Structured persistence still uses
numeric entity ids. See anima-uri.md.
Repository layout (Phase 1 — host/client)
Section titled “Repository layout (Phase 1 — host/client)”Target layout is feature modules under src/features/<slug>/ (UI + protocol + Habitat adapter + domain + plugin.ts). Habitat 管理台 uses the same module shape as chat/task — not a separate admin-* stack. src/features/companion/ is legacy naming; do not add new products there.
End state: Habitat RPC per feature; business methods use POST|WS /rpc/v1 (same envelope). Public health/TLS probes and binary methods (e.g. tts.synthesize) are Habitat RPC REST with auth: optional or Bearer as declared in registry.
Authoritative spec: repository-topology.md.
Host stack: src/host/{kernel,core,engine,capabilities,platform}。Client:
src/client/{portal-sdk,app-frame}。Design system: src/ui-kit/(与 shared/
并列)。Portal Shell: src/portal/app/{tauri,web}。
Platform UI layering
Section titled “Platform UI layering”UI/UX design system (dimensions, visual foundations, components, interaction
patterns) → docs/ui/. Agent hard bans / API →
.agent/rules/ui-dimensions.md,
.agent/rules/frontend-ui.md.
| Layer | Platform-native? | Location | Data path |
|---|---|---|---|
| Shell(壳子维) | Yes | src/portal/app/tauri, companion, Habitat binding | Tauri IPC / commands |
| app frame | Layout follows viewport; settings chrome follows layout band | src/client/app-frame(AppFrame) | Habitat RPC(Feature RPC) |
| Habitat UI | Shell embed(ordinary feature) | src/features/habitat(UI + plugin.habitat.rpc) | Habitat RPC(WS + HTTP POST /rpc/v1) |
| Companion host | Overlay WebView-host(first-party) | src/features/companion/companion(spa attach;thin shell IPC/FS) | Habitat RPC + remote_tools.attach |
Navigation and main layout must use useLayoutMode() / viewport
breakpoints (layout dimension). Do not lock app layout with
getShellKind(). Interaction (context menu / long-press / Enter-to-send)
uses portal-sdk interaction APIs. Visual, component, and pattern norms all
adapt through the same three dimensions.
Boundaries: app-frame and src/features/*/ui reach Habitat via portal-sdk + Feature RPC. Remote tool registration (remote_tools.attach + tool.*) is only for local apps Habitat cannot dial (today: companion first-party overlay / embedded-overlay; shell provides window/IPC/FS only; no Node sidecar). Product surfaces (Chat, etc.) do not attach. Dialable peers use MCP. See .agent/rules/frontend-features.md, docs/ops/habitat-rpc.md.
Habitat navigation ↔ cognitive layers
Section titled “Habitat navigation ↔ cognitive layers”Habitat sidebar is grouped (not flat storage tables). Map new features onto these user-visible concepts:
| Group | Cognitive layer | Routes (representative) |
|---|---|---|
| Runtime | Estate + ops | dashboard, config, cron |
| Memory | Memory | memory browse sub-routes, sleep, auto-llm-runs |
| Self | Self | self-layer, system-prompt |
| Estate | Estate | subjects, worlds |
| Capabilities | Estate (tools) | tools, commands, mcp, acp, remote-tool instances |
FTS 索引维护在 Memory 下(非顶级)。勿新增未映射到上述分组的扁平导航项。
四层模型借鉴认知心理学与 Hindsight 的四网络记忆架构,并有两项根本扩展:感性(情绪)记忆与资源层(资产作为一等公民),以及将自我层从记忆层中独立出来。
数字生命在何处存在、如何存在、能做什么——由两个独立但协作的子系统共同约束。
问题:此刻是什么样的场景?
场景感知是软约束——调节语气、距离、记忆召回偏好与主动性。它不是权限系统,而是调节在场感。
示例维度(非穷尽):
- 话题:情感 / 职业 / 技术 / 哲学 / 历史 / 文学 / 日常
- 活动:角色扮演 / 游戏 / 创作 / 编程 / 阅读
- 氛围:放松 / 专注 / 深夜 / 亲密 / 紧急
Operation: Runs continuously without explicit switch commands. Inferred from dialogue, time, frequency, etc. See time-perception.md.
Environment + health baseline
Section titled “Environment + health baseline”Question: what is my host / runtime quiet state?
Distinct from scene awareness: banded host and process markers (disk, RSS,
deps, MCP/ACP) live as a session-static system-prompt copy, with
event-level Inbox notifications on change. See
environment-awareness.md.
问题:此刻我能使用哪些工具与数据?
能力面具是硬约束——绑定工具集、数据范围与凭证权限。同一数字生命可在不同会话或任务中佩戴不同面具,以防权限泄漏与工具污染。
示例面具:
- 开发者:终端、代码读写、ACP Cursor
- 维护者:逸灵风配置、部署、数据库
- 创作者:文件、笔记、媒体生成
- 研究:网页搜索、论文检索
- 角色扮演:仅对话上下文,无外部工具
- 默认:基础聊天 + 有限查询
运行方式: 在会话边界、显式命令或场景感知触发时切换。每个面具是声明的工具/数据范围,而非独立身份。
二者如何交互
Section titled “二者如何交互”Scene awareness (soft tuning) │ tone, distance, recall bias │ ▼Capability mask (hard constraints) │ tools, permissions, data scope │ ▼Agent behavior- 场景感知推断「我们在做什么」→ 可能建议切换面具并调整在场感
- 能力面具约束「我能做什么」→ 防止跨场景工具误用
- 二者在最终行为中汇合,但各自独立演化
设计草案请开 GitHub Issue(docs 中不设 design-doc 目录)。
记忆存储(摘要)
Section titled “记忆存储(摘要)”| 认知类型 | 说明 |
|---|---|
| Episodic(情景) | 对话归档;保留完整历史 |
| Semantic(语义) | 跨 sessions 的事实、偏好、经历;“how-to” 知识用 procedural 类型 |
| Limbic(感性) | 情绪锚点与印记——“感受到什么” |
| Autobiographical(自传) | 重要经历的意义;按需召回 |
Pipeline: nightly sleep-cycle pipeline (in-process Bun.cron
builtin-sleep-cycle) extracts and maintains memory; memory_recall
retrieves on demand during chat. Details:
memory.md, sleep.md.
保险库与密钥(摘要)
Section titled “保险库与密钥(摘要)”- Vault(User 与 Agent 库中的 ECS
vault_item)为权威密钥存储;遗留的~/.password-store(pass)不会从磁盘删除,但运行时不再读取 - LLM 永远看不到密钥值——仅见保险库条目元数据与 config 引用
- Bootstrap
config.yaml(cold start, before PG): plaintext orenv("KEY")only — notvault(). Runtime PG config:vault("item_id", "field")andenv("KEY"); Shell/vaultfor management - 密钥值不会写入会话归档或日志
See ops/security.md.
Production (standalone install CLI): anima service (systemd
—user). Auto-restarts after crashes; only systemctl stop stops the
service. Source-tree anima does not register service — use just dev habitat for local Habitat.
- Habitat / service: long-running — Habitat HTTP (
/rpc/v1), Discord / WeChat Gateway, cron - UI:
src/portal/app/tauri+web/dist-*bundled SPA (Chat + Habitat); Habitat does not host/habitat
# standalone installanima service start # default: systemd --user (does not auto-build Web)anima service start --foreground # foreground (logs to stdout; systemd unit uses this)anima service status
# monorepo / worktreejust dev # Habitat (≥10000) + Vite Web (≥5000)just dev habitat # Habitat foreground (default random ≥10000; not 2658)just dev web # browser shell Vite HMR from :5000 (set FREEANIMA_URL)just pack web # source deploy / Habitat /web: build dist before start工具架构(三层)
Section titled “工具架构(三层)”工具分三层注册,但对 LLM 暴露为统一的扁平工具列表。LLM 只关心名称与参数,不关心来源。
LLM view — flat tool list: file_read_file(path) ← local file_write_file(path, content) ← local code_execute(code) ← local query_database(sql) ← MCP server send_email(to, subject) ← MCP server acp_cursor(goal, context) ← ACP agent第一层:本地工具
Section titled “第一层:本地工具”- 在逸灵风进程内执行;延迟最低
- 服务启动时自动注册
第二层:MCP 工具(Model Context Protocol)
Section titled “第二层:MCP 工具(Model Context Protocol)”- 连接外部 MCP 服务器(独立进程)
- 每个服务器可注册多个细粒度工具(单次函数调用)
- Configure under Habitat runtime
mcp_servers(PGhabitat_runtime_config); manage in Habitat UI/habitat/mcp(config- start/stop + tools). Shell Settings no longer edits this section.
mcp_servers: database: command: npx args: ["@modelcontextprotocol/server-postgres", "postgresql://..."] transport: stdio env: PGOPTIONS: "-c statement_timeout=5s" remote_habitat: transport: http # Streamable HTTP — use for FreeAnima Habitat /mcp url: http://127.0.0.1:2658/mcp headers: Authorization: "Bearer fa_at_…"第三层:ACP 工具(Agent Client Protocol)
Section titled “第三层:ACP 工具(Agent Client Protocol)”- 每个外部代理实例注册为一个任务级工具:
acp_{name}(goal, context) - 用于完整任务委托(编码、分析、预订等);延迟为秒到分钟级
- Configure under Habitat runtime
acp_agents(PGhabitat_runtime_config); edit in Shell Settings → Habitat 服务 → 服务配置
# habitat_runtime_config fragment (not config.yaml)acp_agents: cursor: command: ~/.local/bin/agent args: ["--force", "acp"] name: cursor description: "Delegate coding, refactoring, and code review"| 维度 | 本地 | MCP | ACP |
|---|---|---|---|
| 运行位置 | 进程内 | 外部服务器 | 外部代理 |
| 粒度 | 函数 | 函数 | 完整任务 |
| 延迟 | 毫秒 | 毫秒–秒 | 秒–分钟 |
| 配置 | 内置 | mcp_servers | acp_agents |
三层可混用;LLM 决定调用顺序;逸灵风负责注册与路由。
Conversation vs AutoLlmRun vs 委托
Section titled “Conversation vs AutoLlmRun vs 委托”轴: 执行期间是否有 user 轮次(与谁触发无关)。
| 类型 | User 轮次 | PG 持久化 | 过程追踪 | 睡眠流水线 |
|---|---|---|---|---|
| Conversation | 是 | sessions + messages(代码仍称 session) | 消息归档 | 参与(浅睡、梦境输入) |
| AutoLlmRun | 否 | auto_llm_runs(经 runAutoLlm()) | 审计行、TTL | 排除 |
| Delegation (ACP) | 否(外部) | 父 conversation + acp_tasks | 可选 | 经父 conversation 返回结果 |
| Script cron | 否 | 仅 cron_log | stdout 文件 | 排除 |
AutoLlmRun 涵盖:cron agent 分支、睡眠 LLM 阶段、未来内部 subagent。工具上下文使用 contextKind: auto_llm,故 memory_remember 不附加 source_conversations。Cron no_agent
shell 脚本不是 AutoLlmRun。
问题:此 conversation 是否应继续朝既定结果推进?
Session Goal 是资源层/编排层的进程内自治循环——区别于 ACP 异步委托:
| 维度 | Session Goal | ACP |
|---|---|---|
| 范围 | 单个 conversation | 外部 agent 任务 |
| 触发 | /goal slash + 回合后 judge | 工具调用 + 回调回合 |
| 持久化 | conversations.goal JSONB | conversations.acp_tasks |
| 延续 | 同一 SSE 流、回合预算 | 任务更新后的独立消息 |
Judge uses optional llm.profiles.goal_judge; on judge call/parse failure
the goal is paused (warn logged + status line in chat). User messages
preempt the loop; /goal pause / /goal resume control auto-continue
without clearing state. See goal.md.
Client UI(web/dist SSOT + 原生壳打包)
Section titled “Client UI(web/dist SSOT + 原生壳打包)”Portal Shell 运行时:Tauri(Rust 主进程 + 系统 WebView;桌面与 Android 统一壳层)。壳规则:.agent/rules/tauri-shell.md。禁止为 companion 再打 Node sidecar;remote_tools.attach 在第一方伴侣浮层(见 Desktop companion)。
UI 源码产物:src/portal/app/web/dist(base: /web/)。
| 客户端 | UI 加载 | 更新方式 |
|---|---|---|
| 浏览器 / PWA | Habitat 托管 /web/*(有 dist 时始终托管) | Service Worker 提示新版本后手动重载(不自动刷新);不跟 GitHub 包通道 |
| Desktop | 安装包内 ui/web(prepare-tauri-ui);调试可用 Tauri dev | 按 bake channel 查 GitHub(release=stable latest + semver;canary=tag canary + commit);用户确认后 NSIS 覆盖;可切换 release⇄canary;About 可选公共 gh-proxy(默认直连) |
| Mobile APK | 安装包内 ui/web(本地同源);Habitat 仅 API | 同上轨语义;有 APK asset 才提示;确认后系统安装器覆盖;可切换轨;同上代理选择 |
| Standalone | 嵌入 Web UI 的单文件 anima | anima upgrade / --channel release|canary / --proxy …;dev / 源码安装不可换轨;curl 安装脚本可用 PROXY=… |
壳层保留原生能力(Tauri commands / prefs / 通知等)。无壳内 UI OTA:原生端不从 Habitat 热替换
SPA。允许用户确认后的安装包级覆盖(Desktop 安装包 / Mobile APK / Standalone anima upgrade
→ 独立前缀如 ~/.anima/standalone)。分发轨 SSOT 为安装包 bake 的
build-meta.channel(release / canary / dev)。Habitat 配置统一走
settings「连接」(/settings);无独立 bootstrap Habitat 页。
Shell vs app frame
Section titled “Shell vs app frame”| Concept | What | Code |
|---|---|---|
| Shell | Portal host runtime(browser / Tauri;形态 web / desktop / mobile) | src/portal/app/*;portal-sdk 中 getShellKind / ShellApi / buildTarget |
| app frame | SPA chrome:模块左栏 Rail / 底栏 Tabs、设置页 chrome | src/client/app-frame(AppFrame);跟视口,不由壳类型锁定 |
三维度模型(壳子 / 布局 / 交互)
Section titled “三维度模型(壳子 / 布局 / 交互)”| 维度 | 驱动 | 职责 |
|---|---|---|
| 壳子 | getShellKind()(web/tauri)+ getShellBuildTarget() | 存储、IPC、Habitat 连接、settings 内容字段、原生能力 |
| 布局 | 仅视口断点(壳不锁底栏/左栏) | compact / expanded;列表 drawer / 并列 / 三栏;settings chrome(tabs vs 侧栏) |
| 交互 | primaryInput(touch / pointer) | 长按 vs 右键、Enter 发送等 |
手机端通常只有窄档,但 手机端 ≠ 窄布局;Portal / 浏览器窗口可以是窄或宽任意档。标准 →
docs/ui/dimensions.md(Agent API →
.agent/rules/ui-dimensions.md)。
| 档位 | 视口 | 布局粗档 | Nav IA | 页内 |
|---|---|---|---|---|
| 窄 | < 768px(Tailwind md) | compact | 底栏 + More | drawer |
| 中 | 768–1027px | expanded | 左侧 Rail | 两栏(清单 drawer) |
| 宽 | ≥ 1028px | expanded | 左侧 Rail | 三栏并列 |
resolveLayoutMode():窄 → compact,中宽 → expanded(URL / config.json
可覆盖)。detectSettingsChromePlatform() 跟布局粗档(设置页 chrome);settings 字段差异由壳子维
resolveShellBindings() / getShellKind() / getShellBuildTarget() 决定。
| 客户端 | UI 加载 | 壳发版 |
|---|---|---|
| 浏览器 / PWA | Habitat /web/* | 随 Habitat / anima upgrade |
| Desktop | 安装包内本地 /web/*(默认) | Tauri 安装包 |
| Mobile APK | 安装包内本地 /web/* | Tauri Android |
| Module | Connection | Notes |
|---|---|---|
| Chat | Habitat RPC /rpc/v1 (shared WS, no remote-tool attach) | /web/chat |
| Habitat | Habitat RPC /rpc/v1 (WS + HTTP POST, same envelope) | /web/habitat/dashboard |
/web/config.json 提供
habitat_url、habitat_ws_url、ui_version、min_shell_version(浏览器/PWA
与壳调试用;原生壳 UI 版本随安装包)。
事件与 Hooks(摘要)
Section titled “事件与 Hooks(摘要)”- EventBus:异步通知传输(Redis 队列);生产代码目前会发出如
session:updated等主题,但无已注册处理器——ACP 回调改用直接onSessionUpdated。不用于睡眠编排。 - Pipeline Runner: explicit DAG for background cycles (sleep-cycle:
light → deep → cross-domain maintenance steps). State in
~/.anima/runtime/pipeline_*_run.json; Habitat API for diagnostics. - Hooks:同步拦截器——在消息入口、回合结束、工具返回等节点做校验或澄清
互补关系:Pipeline Runner 负责定时的多步后台任务;Hooks 处理「进行前/进行中是否允许」;EventBus 保留供未来跨进程扇出,但不在睡眠路径上。
Desktop companion (Habitat SSOT)
Section titled “Desktop companion (Habitat SSOT)”The desktop companion(桌面伴侣)is an unreachable local app that actively
connects to Habitat and registers remote tools in the first-party
companion overlay(伴侣浮层 / embedded-overlay;shell provides window/IPC/FS
only — not a Node sidecar), with a split boundary:
| Concern | Habitat (src/features/companion/) | Local install |
|---|---|---|
| Behavior, slots, active model | companion_profile entity + Habitat RPC | Cache in ~/.anima/companion/config.json |
| VRM / VRMA library | Files on Habitat host + content-hash metadata | Lazy download to desktop cache |
| FBX → VRMA | Habitat service only | Not bundled in desktop installer |
| Settings UI | Habitat RPC + /rpc/v1/companion/* upload | Desktop Settings section (not Habitat) |
| VRM render, float window, patrol | — | Tauri Portal shell + overlay SPA |
Agent tools (bubble, play_slot) | Habitat RPC tool.* after remote_tools.attach | Overlay WebView-host 执行(本地 runtime) |
Remote tools ≠ Portal / MCP: Portal shells and Chat/Settings use Habitat RPC for UI only. Dialable peers expose tools via MCP. Remote-tool attach exists solely when Habitat cannot dial the app (companion overlay today; future independent local apps). Routing uses instance_id (same machine may have multiple instances). See companion.md、habitat-rpc.md.
能力愿景与讨论:GitHub
Issues(标签
enhancement、discussion、security)。本文不跟踪待办。
- 原则与结构写在这里;不含具体任务清单
- 快速变化的行为以运行中的服务为准,而非过时的文字
- 可执行工作放在 GitHub Issues;完成后关闭