## 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
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.
* feat(minecraft): contextflow integration
Add AiriBridge to cognitive engine to enable communication with Airi system. Expose `notifyAiri` and `updateAiriContext` functions in JS planner runtime globals for sending notifications and context updates from agent code.
* refactor(minecraft): remove redundant destinations field from airi-bridge
Remove hardcoded `destinations: ['minecraft']` from spark:command, spark:notify, and context:update events as the destination is already implied by the bridge context.
* feat(minecraft): complete AIRI context flow integration
Wire up bidirectional AIRI ↔ Minecraft communication via dedicated
signal channels instead of reusing signal:chat_message.
- Add airi_command and airi_context to PerceptionSignalType
- Route spark:command intents: action/plan/proposal/reroute emit
signal:airi_command; context intent emits signal:airi_context
- Add inbound context:update listener so AIRI can push context to
the Minecraft agent
- airi_context signals are injected into conversation history directly
without triggering a full cognitive cycle
- airi_command events reset the no-action budget (like player chat)
- enterContext/exitContext auto-emit context:update back to AIRI for
task lifecycle visibility
- Add sendEmit() helper for queued/working/done progress reporting
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(minecraft): report bot startup state to AIRI
Send initial context update to AIRI when brain comes online, including
bot username, server address, position, health, game mode, and list of
other online players. Tagged with 'startup' and bot username for
filtering.
* feat(minecraft): manage bot config through airi
* feat(stage-ui): add minecraft service shell
* fix(stage-ui): use applied minecraft config for chat context
* fix(minecraft): fall back on invalid env port
* fix(minecraft): support quoted env values
* fix(minecraft): ignore empty env overrides
* fix(stage-ui): keep minecraft draft during apply
* fix(stage-ui): simplify minecraft heartbeat label
* feat(stage-ui): simplify minecraft settings shell
* fix(minecraft): use registry heartbeat for stage liveness
* chore(minecraft): remove annoying detector decision logging
* fix(minecraft): limit context flow to bot pushes
* fix(minecraft): use workspace server sdk
* fix(stage-ui): replay registry snapshots for late listeners
* chore(minecraft): add todo for explicit stage deregistration
* feat: improve context flow observability
* fix(stage-ui): remove redundant header and callout from settings and context flow pages
* feat(stage-ui): enhance context flow prompt projection UI with readiness indicator
* docs(stage-ui): clarify context flow prompt projection terminology
* fix(stage-ui): add test for clone-safe context snapshots with nested fields
* todo
* fix(minecraft): avoid blocking startup on airi connection
* Remove LLM timeouts from the Minecraft brain
* Remove context boundary system from Minecraft brain
* feat(minecraft): use isolated-vm for JS planner sandbox
* refactor(minecraft): harden planner sandbox defaults
* Remove LLM attempt timeout guard
* [autofix.ci] apply automated fixes
* Fix server runtime shutdown signal handling
* Remove misleading Minecraft integration toggle
* contextflow destination to stage-*
* chore(deps): updated
* Add settings layout route for web devtools
* chore: default to expand context panels
* fix(server-*): should export more types, and for module:announced should ignore self
* refactor(minecraft): better context orchestration, handle module announce, context sync, and more
* feat(stage-ui): not spark command ready
* [autofix.ci] apply automated fixes
* clean up
* refactor: use :class arrays per AGENTS.md styling guidelines
* cleanup bloated tests
* rm more tests
* use errorMessageFrom
* hardcode to reduce bloat
* update setup instructions
* timeout for brain
* remove more bloat
* fix
---------
Co-authored-by-agent: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by-agent: Codex
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Neko Ayaka <neko@ayaka.moe>
* fix: resolve lint issues
## Summary
Fix lint issues identified by the linter.
## Changes
- **app.js**: Use `Number.isNaN()` instead of global `isNaN()`
- **app.js**: Prefix unused variable `result` with underscore
- **scheduler.ts**: Remove unused variable `log`
## Details
- `Number.isNaN()` is the preferred way to check for NaN in modern JavaScript
- Unused variables are flagged by the linter and should be removed or prefixed with underscore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
---------
Co-authored-by: hobostay <hobostay@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Garfield Lee <Garfield550@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
* fix(minecraft): downgrade minecraft-data to 3.102.3
Serialization error for play.toServer : Write error for undefined : The value of "value" is out of range. It must be >= -128 and <= 127. Received 218 stack=RangeError [ERR_OUT_OF_RANGE]: Write error for undefined : The value of "value" is out of range. It must be >= -128 and <= 127. Received 218
* fix(minecraft): close existing MCP transports on client reconnect
Handle client refresh scenarios by closing existing streamable and SSE transports before creating new ones, preventing resource leaks and connection conflicts.
Replaces flat message list with collapsible turn cards (user+assistant pairs). Parses user messages into tagged sections ([EVENT], [FEEDBACK], [PERCEPTION], etc.) with inline/collapsible rendering based on content type. Adds context status bar showing active context label and archived summaries. Introduces Brain.broadcastConversationState() to emit full context metadata (active
Introduces task context boundaries via enterContext()/exitContext() REPL functions. Active context messages remain in full; completed contexts are summarized and archived. Adds [CONTEXT_HISTORY] prefix message with archived summaries, auto-trim when active context exceeds 30 messages, and auto-collapse when >10 summaries accumulate. Provides history query runtime (recent/search/playerChats/
Removes cooldown_seconds parameter and timer-based resumption from giveUp action. Brain now uses boolean givenUp flag instead of giveUpUntil timestamp. Action halts all autonomous processing until next player chat message. Updates error-burst guard to remove suggestedCooldownSeconds field. Adjusts prompts, tests, and MCP server to reflect halt-until-input semantics.
Strips ring buffer history storage, getHistory(), getEventsByTrace(), and historySize config from EventBus. Removes logger dependency and default config object. EventBus now only handles emit/subscribe/dispatch without persistent event storage. Updates container to use zero-config createEventBus(). Moves event-bus from cognitive/os/ to cognitive/ directory.
Update services/minecraft/codex-skills/minecraft-debug-mcp/references/mcp-surface.md
Update services/minecraft/codex-skills/minecraft-debug-mcp/references/mcp-surface.md
Update services/minecraft/codex-skills/minecraft-debug-mcp/SKILL.md
Strips saliency thresholds, window counters, signal generation, and route filtering from all perception event definitions and EventRegistry. Events now emit raw data directly via onRawEvent callback without conscious/reflex/debug routing or threshold-based filtering. Removes WindowCounter, SaliencySnapshot, and related timer/slot logic.
Plugin loadPlugin calls were fire-and-forget during reconnect, allowing spawn
event handlers to run before plugins finished loading. Now initializeReconnectPlugins
runs sequentially and spawn waits for completion before invoking spawned hooks.
When stop() is called before detachFromBot(), mineflayer listeners remain
attached. Nullifying context ensures handleMineflayerEvent's guard clause
silently ignores any events that fire in this window.
Action tools were defined with configurable: false, preventing updates after
the first evaluate() call. New defineUpdatableGlobal uses configurable: true
so installActionTools can redefine them when available actions change.
- Store and clean up EventBus subscription and TaskExecutor listeners in destroy()
- Clear stopCancelledControlActionIds Set in destroy() to prevent unbounded growth
- Use setImmediate in enqueueEvent to prevent re-entrant processQueue bypassing isProcessing guard
- Add conversation history trimming (max 40 messages) to prevent exceeding LLM context window
- Remove duplicate pause check block before REPL execution
Add PatternRuntime to brain sandbox exposing patterns.get/find/ids/list helpers for known-working recipes, update mcp-surface.md to document patterns global, add patterns to brain-prompt.md globals list with usage guidance, expose patterns in js-planner sandbox and introspection, add test coverage for patterns.get/find in REPL, integrate matchesBlockAlias in breakBlockAt action to support variant-aware block verification
[autofix.ci] apply automated fixes
chore(minecraft): cleanup
[autofix.ci] apply automated fixes
Remove greetingBehavior from reflex system, delete lastGreetingAtBySpeaker tracking from ReflexSocialState and context snapshot, unregister greeting behavior from ReflexManager, clean up stale comments about greeting behavior compatibility
Remove returnValue assignment from sandbox.lastRun after script execution (keep only returnRaw for typed values), add test verifying prevRun does not expose stringified returnValue property, update brain-prompt.md to remove returnValue references and guide users to stringify returnRaw explicitly for text output (JSON.stringify(prevRun.returnRaw)), update value-first rule examples to use prevRun.returnRaw instea
Replace LLM traces panel with live conversation view showing real-time chat messages, add ConversationUpdateEvent/RequestConversationCommand types, implement emitConversationUpdate in Brain to broadcast conversation state changes (on forgetConversation/turn completion/errors), add session boundary tracking to grey out cleared conversations, implement typing indicator during LLM processing, add collapsible system
Remove autoCraft action (redundant with craftRecipe's auto-handling of intermediate materials), update craftRecipe description to clarify num parameter is craft count not output item count (e.g. crafting planks once yields 4 planks), fix ensurePlanks to pass logsToCraft instead of logsToCraft*PLANKS_PER_LOG to craftRecipe, fix craftRecipe to use replaceAll instead of replace for space norm
Add try-catch wrapped bot.chat call in executeGiveUpAction to broadcast "[debug] Giving up for {cooldownSeconds}s: {reason}" message, log warning on chat failure
Add pause checks at start of each retry attempt, after backoff sleep, and before REPL execution to allow !pause command to interrupt brain processing mid-turn, log interruption events with scheduler tags tracking attempt number and event context
Add NoActionBudgetState interface tracking remaining/default/max budget, implement budget system with DEFAULT=3/MAX=8 limits and STAGNATION_REPEAT_LIMIT=2, add setNoActionFollowupBudget/getNoActionBudgetState/resetNoActionFollowupBudget methods, track stagnation via buildNoActionSignature comparing returnValue+logs across turns, block follow-ups when budget exhausted or stagnated and emit brain
Add test confirming executeStopAction cancels active control action (goToPlayer), marks it as cancelled in queue snapshot, calls bot.interrupt, and does not enqueue failure feedback event for the cancelled action
Extract normalizeReplCode/rewriteTrailingExpressionToReturn from Brain to new repl-code-normalizer module, add test verifying single-line statements with trailing expressions return values (const nearestLog = [...]; nearestLog)
Add ControlActionQueueEntry/ActionQueueSnapshot types tracking action state (pending/executing/succeeded/failed/cancelled), implement control action queue with MAX_QUEUED_CONTROL_ACTIONS=5 and MAX_PENDING_CONTROL_ACTIONS=4 capacity limits, add enqueueControlAction to queue async control actions (skip chat/skip/stop/readonly tools) instead of blocking turn completion, implement runControlActionWorker processing
Add includeBuiltins parameter to Brain.getReplState/JavaScriptPlanner.describeGlobals to optionally skip REPL builtins (skip/use/log/forget_conversation), default to excluding builtins in get_state MCP tool to reduce noise (pass includeBuiltins:true to include them), update SKILL.md documenting builtin filtering behavior, add tests verifying get_state calls getReplState with includeBuiltins flag, ad
Add event priority system (player_chat=0, perception=1, feedback=2, no_action_followup=3) with getEventPriority helper, implement coalesceQueue() to stable-sort queue by priority and drop redundant no-action follow-ups when player chat is waiting, call coalesceQueue before each queue shift to ensure player messages are processed first, add tests verifying chat promotion/followup dropping/order preservation