- Updated various components in the llm-router to include dark mode styles, ensuring better visibility and aesthetics in dark theme.
- Added tests for API URL helpers to validate sign-in URL construction and redirection logic.
- Improved the sign-in flow to handle trusted redirects for standalone admin origins.
- Enhanced CSS styles for dark mode, including adjustments to backgrounds, borders, and text colors for better contrast and readability.
- Refactored input components to maintain consistent styling in both light and dark modes.
Add a form-first LLM/TTS router config editor and a redacted admin config snapshot so operators can inspect configKV state before applying changes.
Preserve existing encrypted key entries when loaded slices are submitted without new plaintext keys.
Signed-off-by: RainbowBird <git@luoling.moe>
Commit-Message-Assisted-by: Claude (via Claude Code)
- Added `prompt: 'select_account'` for Google and GitHub providers to force account selection during OAuth linking.
- Introduced localized error messages for account linking issues in multiple languages.
- Implemented a function to resolve OAuth error codes to specific i18n keys for better user feedback.
- Updated account settings page to display relevant error messages based on OAuth linking status.
## Summary
Restores `services/minecraft` to own **only Minecraft semantics**,
decoupling the already-merged #1915 runtime contract from the (unmerged)
#1916 desktop-relay design — as requested by @shinohara-rin in the #1916
review:
> I'd prefer we first restore `services/minecraft` to only own Minecraft
semantics, then reintroduce desktop relay/read-aloud through a generic
module capability/tool contribution path or a Minecraft adapter.
Otherwise `main` now contains half of a cross-PR runtime contract whose
other half we are saying should not land as-is.
The perception/reflex/brain reliability work from #1915 is untouched.
This PR only removes the three desktop-coupling points baked into the
bot service.
## Changes
- **`airi-bridge.ts` — `handleActionIntent`**: a `spark:command` is
high-level guidance from the AIRI server, now attributed to a neutral
`'airi'` source. Removed the hardcoded `username = '主人'` / `relayedFrom:
'desktop-airi'` "treat it as if the master typed it in-game" framing.
The generic server→bot directive still routes through
`signal:chat_message` to trigger a fresh decision cycle, exactly as
before — only the identity/provenance is neutralized. Binding a relayed
command to the master's in-game identity is desktop-relay policy and
will live in the Minecraft adapter.
- **`minecraft-context-service.ts`**: stopped emitting the
machine-readable `master:` status hint (whose only consumer was the
desktop `gaming-minecraft` store) and removed the desktop-coupling
NOTICE. The owner identity remains in the human-readable status **text**
for the bot's own brain.
- **`cognitive/index.ts`**: stopped forwarding the bot's own in-game
chat over the `context:update` lane `minecraft:speech` (only meaningful
with the #1916 desktop TTS consumer). The bot still ignores its own
messages.
## How tested
- Updated `minecraft-context-service.test.ts` to assert the neutral
behavior (owner identity in status text, **never** as a `master:` hint).
2/2 pass.
- `pnpm exec eslint <changed files>` → 0 problems.
- The changed files typecheck clean. (Note: this worktree surfaces
pre-existing `vec3@0.1.10` vs `vec3@0.2.0` dependency-resolution errors
in unrelated files —
`gaze.ts`/`runtime.ts`/`patched-goto.ts`/`world.ts`/`map-renderer`/`brain`/`rules`
— present on `main` before this change too; not introduced here.)
## Follow-up
Desktop relay (`relayToMinecraft`) and read-aloud will be reintroduced
through a Minecraft adapter in the renderer (registering tools/prompts
into the existing generic stores), so the runtime contract is owned by
the Minecraft surface rather than baked into the neutral bot service.
The generic stage-ui robustness fixes are already split out in #1949.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Rin <shinohara-rin@users.noreply.github.com>
## Summary
Two small, generic robustness fixes, split out of the Minecraft desktop
integration (#1916) so they can land independently of that rework — as
suggested in @shinohara-rin's review:
> The generic fixes in this PR, like the TTS session cleanup and
`spark:command` result handling, seem separable and worth keeping in a
smaller PR.
Both are in shared `stage-ui` runtime code and contain **no
Minecraft-specific logic**.
## What's included
- **`spark:command` result handling**
(`tools/character/orchestrator/spark-command.ts`):
`command.destinations` may be `undefined` — the channel sender
(`stores/llm.ts` `sendSparkCommand`) deletes it to broadcast to all
authenticated peers. The success message's `.join()` therefore surfaced
`Cannot read properties of undefined (reading 'join')` back to the LLM
even though the send had already succeeded. Guard it and report a
broadcast instead.
- **TTS session isolation** (`components/scenes/Stage.vue`
`openTtsSession`): a completing/erroring session now only clears the
module-level `currentSession` if it **is** that session. The previous
code cleared it whenever any `stream-` session completed, which becomes
unsafe once sessions exist that are not assigned to `currentSession`
(e.g. one-off read-aloud sessions) — one of those finishing would null a
still-active chat session and drop the rest of the reply.
## How tested
```bash
pnpm -F @proj-airi/stage-ui exec vitest run src/tools/character/orchestrator/spark-command.test.ts # 9 passed (+1 new)
pnpm -F @proj-airi/stage-ui typecheck # 0 errors
pnpm exec eslint <changed files> # 0 problems
```
- Regression test for the broadcast-destinations result message.
## Context
This is the first, low-risk slice of reworking the Minecraft↔desktop
integration around the neutral Context Flow architecture (per the #1916
review). The Minecraft relay/read-aloud behavior will be reintroduced
through a Minecraft-owned adapter in a follow-up.
---------
- Removed specific catalog references for '@unocss/core', 'es-toolkit', 'nanoid', and 'valibot' in pnpm-workspace.yaml and various service package.json files.
- Updated versions for '@vueuse/core', 'es-toolkit', 'nanoid', 'reka-ui', and 'valibot' to their latest compatible versions.
- Cleaned up unused catalog entries in pnpm-workspace.yaml.
## Summary
This PR adds the current Stage Godot avatar presentation path:
avatar-only same-frame glow plus tuned toon color mapping.
<img width="994" height="951" alt="屏幕截图 2026-06-02 015159"
src="https://github.com/user-attachments/assets/feb94b95-745f-4b47-aba2-0289dafecd1c"
/>
<img width="1769" height="1279" alt="屏幕截图 2026-06-02 021212"
src="https://github.com/user-attachments/assets/d4437dc2-e859-42ca-b3fd-0a90e55d641b"
/>
## Design
The implementation uses three layers:
1. Base avatar material rendering still comes from the vendored V-Sekai
MToon shader.
2. `StageAvatarGlowRuntime` marks visible avatar meshes through a
depth-tested `MaterialOverlay` stencil pass.
3. `StageAvatarGlowCompositorEffect` reads that stencil mask in the same
frame, extracts avatar pixels, builds the glow pyramid, composites
glare, and applies the current NAES/toon color mapping.
This avoids Godot Environment Glow because that path is global. Here,
source selection needs to be avatar-specific and controlled by the stage
runtime.
It also avoids an extra SubViewport path because prior testing showed
camera-motion lag. The compositor path keeps the effect in the same
render frame.
## Stage Baseline
`StageVisualPreset` now keeps the stage environment neutral for this
effect:
- skybox is visible as background only
- skybox does not drive avatar/ground ambient light
- reflected light is disabled
- Godot Environment Glow is disabled
- Godot tonemap/adjustment stay neutral
- custom color mapping runs in the compositor
## Notes
`StageAvatarGlowCompositorEffect` currently owns both avatar glow and
toon color mapping. That is acceptable for this PR because it is the
only custom stage compositor today.
Before adding rim light, screen-space outlines, or more post effects,
compositor ownership should be split from individual features so effects
can register passes instead of replacing `Camera3D.Compositor`
independently.
Move Voice Pack creation and editing to dedicated admin routes, add catalog-backed free-text fields, and wire test audio generation through the public speech API.
Document the mock-API browser verification workflow so future local UI checks can avoid auth and tooling dead ends.
Signed-off-by: RainbowBird <git@luoling.moe>
Add PostHog product events for manual TTS stop clicks and conversation controls across Web, mobile, and Electron chat surfaces. Document the events in metrics ownership and cover the analytics API with Vitest.
Signed-off-by: RainbowBird <git@luoling.moe>
Commit-Message-Assisted-by: Codex
Match the mobile manual TTS stop control to the subtler Web chat button treatment by removing the bright filled circle and using neutral icon styling with primary hover feedback.
Signed-off-by: RainbowBird <git@luoling.moe>
Commit-Message-Assisted-by: Codex
Add the stop-speaking control to the mobile shared input layout and the Electron Tamagotchi chat input so Web/shared, mobile, and Electron all expose the same manual TTS interruption path.
Signed-off-by: RainbowBird <git@luoling.moe>
Commit-Message-Assisted-by: Codex
Track per-app TTS concurrency in Redis, route capped upstreams by
available pool capacity, and surface pool saturation metrics. Document
the Voice Pack plan so the remaining backend and card-binding work has
an explicit implementation map.
## Summary
This PR upgrades the Minecraft bot's cognitive stack so it perceives
danger
accurately, reacts below the LLM brain with fast reflexes, and recovers
from
common brain failure modes. All changes are confined to
`services/minecraft/**`.
The desktop-side integration (spoken in-game chat, the online-gated
relay tool,
master binding in the UI) is submitted separately to keep this PR
focused; the
two are coupled only at runtime via AIRI context lanes, not at compile
time.
## What's included
**Perception — accurate damage attribution**
- `fall-tracker`: classify fall damage from physics-tick vertical
velocity.
- `attacker-tracker`: record the *real* attacker from the `entityHurt`
source,
fixing "a mob shot me but I chased the player standing next to me".
- `low-health`: emit a danger signal at health ≤ 6 when no ready food is
held.
- `damage-taken`: resolve the source via a lava → drown → fire → fall →
attacker chain and surface the attacker's name to the brain.
**Reflex — autonomic behaviors (run on the FSM tick, below the brain)**
- `defend`: auto-engage a hostile mob that attacks the bot/master and
hold the
fight instead of thrashing (suppress damage wakes while attacking).
- `escape-hazard`: climb out of lava, or surface when drowning.
- `auto-eat`: eat ready food at health ≤ 6 (skipped during combat).
- A `reflexEngaged` autonomy flag suppresses auto-follow and auto-eat
while a
defend/escape reflex owns the body.
**Conscious / skills — master recognition and reliability**
- Bind the "主人" role to the owner's in-game username so the bot
recognizes its
master in-world; enforce master-only command authority, never attack the
master, and react to a light hit with a short protest. Resolve players
by
username, never the literal "player"/"主人".
- `js-planner`: strip prose-mixed LLM replies that caused `X is not
defined` and
give-up spirals; add a `botCall` sandbox bridge and the `whereName`
query
chain method.
- Brain-prompt discipline: *saying is not doing*, *`recipePlan` is recon
not
crafting*, *eat only when food < 18* (regen is time-based), *defer equip
until
a queued craft lands*.
- Skills: collect drops that spawn shortly after a kill (no more 0
loot);
`goToBed` skips occupied beds; detach auto-follow while
mining/collecting so
digging is not interrupted.
- Platform: load perception rules on Windows (`fileURLToPath`); widen
the AIRI
client read timeout to stop connection flapping.
The master username is injected via `generateBrainSystemPrompt(..., {
masterUsername })`
from config — it is **not** hardcoded.
## How tested
```bash
pnpm -F @proj-airi/minecraft-bot exec vitest run # 220 tests; +56 new, all green
pnpm -F @proj-airi/minecraft-bot typecheck
pnpm exec moeru-lint services/minecraft # 0 problems on changed files
```
- Each feature ships with unit tests (trackers, reflex behaviors,
planner
salvage, skills, prompt, context service).
- Manual in-game testing: combat vs. pillagers/zombies, lava/water
escape,
low-health eating, crafting, master recognition with multiple players
present.
### Pre-existing baseline (not introduced by this PR)
Measured on `main` (`cb5c0783e`) before any change here:
- `tsc` reports 12 errors, all from a `vec3` 0.1.x/0.2.0
dependency-dedup
mismatch (`angleTo`) and `unknown[]` casts in `map-renderer.ts` /
`mcdata.ts` —
files this PR does not touch. This PR adds **0** new type errors.
- 7 unit tests already fail on `main` (4 in `map-renderer.test.ts`, 2
timing-sensitive `brain.test.ts`, 1 timing-sensitive `rules.test.ts`).
This
PR leaves those exactly as-is and does not touch those modules.
## Known limitations / follow-ups
- The `defend` reflex does not yet reliably engage ranged pillagers at
distance;
the brain's `attack` tool currently covers that case.
- `craftRecipe` does not auto-unpack blocks (e.g. diamond_block →
diamond) or
auto-gather missing intermediates for complex recipes.
- `inferDamageSource` orders environmental causes before
`recentAttacker`, which
can mis-attribute an in-water-while-shot hit; low impact, deferred.
## Description
Unfortunately the method of manually calling CI on the PR branch used by
#1907 doesn't count as status check of that PR (#1924), probably because
the called workflow inherits the context of the calling workflow, which
is not triggered by the PR. I read the docs and the most straightforward
solution is using a PAT, which does trigger the pull_request event.
Alternatively you can open PR with a custom github app, which is more
complicated but allows the app to bypass ruleset and commit directly to
main. Or just disable mandatory status checks.
## Linked Issues
## Additional Context
<!-- e.g. is there anything you'd like reviewers to focus on? -->
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Rin <shinohara-rin@users.noreply.github.com>