mirror of
https://github.com/moeru-ai/airi.git
synced 2026-08-14 00:48:06 +00:00
> **Reworked.** This PR has been rebuilt around the neutral Context Flow architecture, per @shinohara-rin's review. Minecraft is no longer special-cased in the generic stage-ui runtime — desktop relay & read-aloud are now reintroduced through a **Minecraft adapter** that contributes into the existing generic stores. ## Stacked PRs (please review/merge in order) This rework is split as you suggested — "first restore `services/minecraft` to only own Minecraft semantics, then reintroduce desktop relay/read-aloud through ... a Minecraft adapter": 1. **#1949** — generic stage-ui robustness fixes (spark:command result guard + TTS session isolation), split out as you noted they were separable. 2. **#1950** — `refactor(minecraft)`: restore `services/minecraft` to neutral Minecraft semantics (removes the desktop-relay assumptions baked into the merged #1915 — `handleActionIntent`'s `username='主人'`/`relayedFrom`, the `master:` status hint, and the `minecraft:speech` forwarding). 3. **this PR** — reintroduces desktop relay & read-aloud via the Minecraft adapter. Because #1949 and #1950 are not merged yet, their commits currently appear in this PR's diff. Once they land I'll rebase this PR onto `main` so the diff shrinks to just the adapter work. ## The adapter (`apps/stage-tamagotchi/src/renderer/stores/minecraft/`) The renderer owns the entire desktop ↔ in-game-bot integration and contributes into the **existing** generic stores — the same pattern as `mcp-tools.ts` / `plugin-tools.ts`: - **`relayToMinecraft` tool** → `useLlmToolsStore.registerTools('minecraft', …)`, registered **only while the bot is online** (a hard capability gate, replacing the old prompt-only "don't relay when offline"). `execute()` re-checks availability, so a relay is never acked after the bot disconnects. - **Persona directive** → `useLlmToolsetPromptsStore.registerToolsetPrompts('minecraft', …)`, re-registered whenever online/master/runtime-context change so the model gets a fresh directive each turn. - **Read-aloud** → consumes the bot's `minecraft:speech` chat into the stage TTS (Chinese-gated), and binds 主人 by **parsing the bot's neutral status text** — no desktop-specific hint from the bot service. - **Notify muting** → `orchestratorStore.muteNotifySource('minecraft-bot')`. ## Generic, non-Minecraft additions - **`useSystemSpeechStore`** (stage-ui): a neutral bridge so any module can voice a one-off system line; `Stage.vue` consumes it via independent, tracked TTS sessions cancelled on unmount / provider-or-voice change. - **`orchestrator.muteNotifySource(id)`**: a generic primitive so a module suppresses only **its own** notifies — every other module/plugin notify still reacts (this fixes the earlier P1 where all `character`-targeted notifies were dropped). - **`./tools/*` export** from stage-ui so app-side tool authors can reuse the shared spark-command normalizers. ## services/minecraft Re-adds the bot's own-chat forwarding on `minecraft:speech`, now landing **together with** its adapter consumer so the read-aloud contract is never half-present on `main`. ## How tested - `pnpm -F @proj-airi/stage-ui typecheck` + `pnpm -F @proj-airi/stage-tamagotchi typecheck` → 0 errors. - 16 new unit tests (persona prompt builder + relay tool: availability gate, do/stop, full-label fidelity, master parsing, read-aloud gating); orchestrator suite 5/5. - `eslint` → 0 problems. ## Addressed review points - Restore non-Minecraft notifications → generic `muteNotifySource` (only the bot's source is muted). - Isolate / track-and-cancel one-off system TTS sessions → `Stage.vue` `oneOffSessions`. - Re-check bot availability before relaying → `isAvailable()` in `execute()`. - Read the master hint that actually exists → desktop now parses the master from neutral status **text** (the `master:` hint is removed in #1950). - Defer Minecraft init until after channel config → adapter `setup()` runs after the configured `serverChannelStore.initialize(...)`. --------- Co-authored-by: Rin <shinohara-rin@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>