Hybrid Research Rig — Ensemble AI Decision Engine, Ender Dragon Automation, Vision, HUD & Security Hardening#716
Conversation
…DB memory
Adds the 3-phase ensemble pipeline used by CloudGrok:
- panel.js: queries 4 Grok models in parallel (60s timeout)
- arbiter.js: heuristic scoring (length, completeness, action quality, latency);
escalates to judge when top-2 within 0.08 margin
- judge.js: LLM-as-judge (grok-4) picks best response; 30s timeout with fallback
- feedback.js: ChromaDB vector memory (3072-dim Gemini embeddings); retrieves
similar past decisions (similarity > 0.6) and injects as [PAST EXPERIENCE]
- logger.js: writes every decision to bots/{BotName}/ensemble_log.json
- controller.js: EnsembleModel class — drop-in replacement for any single model
Integration: profile.model = 'ensemble' routes through EnsembleModel, which
implements the same sendRequest() interface as all other model providers.
fe74365 to
01679b6
Compare
…tone pathfinding Ender Dragon automation (dragon_runner.js + dragon_progress.js): - 6 gameplay chunks: getDiamondPickaxe, buildNetherPortal, collectBlazeRods, collectEnderPearls, locateStronghold, defeatEnderDragon - Persistent state (dragon_progress.json) with atomic writes and corruption recovery - 5 retries per chunk with exponential backoff; death recovery returns to drop coords - !beatMinecraft / !dragonProgression commands (120-180 min timeout) Baritone A* pathfinding (RC25+): - Custom A* pathfinder replacing mineflayer-pathfinder; distance-adaptive timeouts - Ghost block handling for Paper servers (re-fetch block after nav) - isClearPath() with Baritone integration; null-guard on isWalkable for respawn Skills RC13-RC29 (skills.js + world.js): - RC13: safeToBreak filter fix for tree logs - RC14-17: multi-hop smart explore (200-block relocation), water avoidance, wider collect range - RC18-20: resilient collectBlock — retry on combat, exclude failed positions - RC22: Aikar GC flags; RC23: bypass bot.collectBlock.collect() for Paper - RC24: timeout-protected dig (goToPosition 15s, dig 10s, pickup 8s) - RC26: prefer doors over block-breaking; stale dig fix (re-fetch after nav) - RC27: 9 runtime bug fixes from log review
Vision system (src/agent/vision/): - Dynamic import() for camera module with graceful fallback if WebGL unavailable - Xvfb + Mesa software rendering in Docker (LIBGL_ALWAYS_SOFTWARE=1) - 2-second delay after Xvfb start for WebGL context initialization - Patched prismarine-viewer: entity bone parent null check, unknown entity suppression - Per-bot vision model support (grok-2-vision-1212 for CloudGrok) HUD overlay (mindserver.js + public/index.html): - Gaming-style web dashboard at :8080 - Per-bot panels: runtime tracker, current goal, action display, scrollable command log - Live bot camera feeds via protocol-aware viewer iframes - Toolbar with bot controls; responsive CSS Discord bot (discord-bot.js): - Direct bot chat via Discord channels - Admin commands: !start, !stop, !restart with group-based control - Auto-fix monitor: watches bot-output events for errors, suggests fixes - Role-based access (DISCORD_ADMIN_IDS), usage tracking (!usage [agent|all]) - Path traversal guard + command injection detection on all user input - MindServer integration: live agent status display Windows launcher (start.ps1): one-command start/stop/detach for all bot profiles
…ctions, key loading New security modules: - message_validator.js: injection detection (shell commands, backticks, pipe-to-shell), character sanitization, and length limits for Discord/Minecraft chat - rate_limiter.js: sliding-window per-user limiter with automatic stale entry cleanup - usage_tracker.js: token usage tracking with cost estimation for active providers Existing file hardening: - keys.js: environment variables always override keys.json; added .env support - speak.js: TTS sanitization to prevent command injection in text-to-speech - commands/index.js: isCommandBlocked() check against per-profile blocked_actions array; settings.js deepSanitize() strips __proto__, constructor, prototype from SETTINGS_JSON
…Grafana monitoring Docker / Compose: - docker-compose.aws.yml: production config with LiteLLM proxy (:4000), ChromaDB, Tailscale sidecar, ENFORCE_SECURE_PROFILE=FALSE for mineflayer chat - docker-compose.yml: dev compose with Ollama host routing, port 19565 (was 25565) - Dockerfile: non-root user, Xvfb/Mesa for vision, memory 1536M→2560M - Tasks.Dockerfile: separate image for task evaluation runner - .dockerignore: exclude bot logs, node_modules, world saves from build context AWS scripts (aws/): - ec2-go.sh: one-command deploy (pull/rebuild/restart); IMDSv2 support, auto-detects local vs remote execution - setup.sh: full EC2 provisioning — Docker, Tailscale, ChromaDB, environment setup - deploy.sh: rsync-based deployment with SSM secret pulling - ec2-deploy.sh: self-contained bootstrap for EC2 browser SSH - env-toggle.sh: switch between cloud/local/hybrid environment configs - backup.sh / restore.sh: S3 world backup and restore - setup-ollama-proxy.sh: socat systemd service for Tailscale→Ollama routing Observability: - prometheus-aws.yml: Prometheus scrape config for EC2 deployment - grafana-provisioning/: dashboards, datasources, and alerting rules Security: - whitelist.json: pre-built offline UUIDs (avoids Playerdb crash for ONLINE_MODE=FALSE) - .env.example / keys.example.json: API key templates - .husky/pre-commit: ESLint zero-warning gate on every commit Patches: - prismarine-viewer: entity bone parent null check, unknown entity suppression
…ation, ESLint, and CI/CD
There was a problem hiding this comment.
Pull request overview
This PR introduces a “Hybrid Research Rig” setup for running multiple autonomous Minecraft agents concurrently (cloud ensemble + local GPU), adds an ensemble decision pipeline with ChromaDB-backed experience retrieval, expands automation/task profiles (notably Ender Dragon progression), and includes multiple security/ops hardening changes across runtime, Docker/AWS, and messaging.
Changes:
- Adds an ensemble model controller (panel → heuristic arbiter → optional LLM judge) with decision logging and ChromaDB similarity memory.
- Adds/updates infra & runtime features: remote agent support, usage tracking, rate limiting/message validation, Docker/AWS scripts/configs.
- Expands profiles/tasks for dragon progression and multi-mode provider routing.
Reviewed changes
Copilot reviewed 146 out of 147 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
Tasks.Dockerfile |
Reworks the tasks runner image (Node 22 slim, Java 21, AWS CLI, non-root) and switches to copying repo source instead of git clone. |
package.json |
Adds/updates dependencies and introduces prepare/lint/lint-staged scripts and additional overrides. |
src/utils/usage_tracker.js |
Adds per-agent token/cost usage tracking with periodic persistence and rolling RPM/TPM stats. |
src/utils/rate_limiter.js |
Adds an in-memory sliding-window rate limiter with periodic stale-entry cleanup. |
src/utils/message_validator.js |
Adds message validation/sanitization for Discord and Minecraft chat plus username validation. |
src/utils/keys.js |
Makes env vars override keys.json, adds sanitization and one-time warnings for legacy key usage. |
src/ensemble/* |
Adds ensemble querying, scoring, judging, logging, and ChromaDB-backed feedback/memory retrieval. |
src/process/init_agent.js |
Adds remote MindServer connection mode and global handlers for uncaught errors/rejections. |
src/process/agent_process.js |
Adds remote-agent spawn arguments, restart/backoff logic, and process.execPath spawning. |
Dockerfile |
Improves caching, runs tests in build, and drops root privileges for runtime. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| COPY ./server_data.zip /mindcraft/ | ||
| RUN unzip -q server_data.zip && rm server_data.zip | ||
|
|
||
| RUN npm ci --omit=dev |
There was a problem hiding this comment.
npm ci --omit=dev will skip devDependencies, but this repo relies on install scripts that invoke dev tools (e.g., postinstall: patch-package and prepare: husky install in package.json). This is likely to fail the image build because patch-package/husky won’t be present. Consider either (1) running npm ci without --omit=dev and then pruning dev deps, or (2) disabling install scripts (--ignore-scripts / HUSKY=0) and ensuring patches are applied another way.
| RUN npm ci --omit=dev | |
| RUN npm ci && npm prune --omit=dev |
| read -r -p "Are you sure? Type 'yes' to confirm: " CONFIRM | ||
| [[ "$CONFIRM" == "yes" ]] || { echo "Aborted."; exit 0; } | ||
|
|
||
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=no" |
There was a problem hiding this comment.
This restore helper also uses ssh with -o StrictHostKeyChecking=no, which disables host key verification and enables transparent man-in-the-middle of the SSH session. A network attacker could impersonate the EC2 host so that your restore runs against an attacker-controlled machine, potentially exposing world data or other state. Replace StrictHostKeyChecking=no with accept-new (or pre-seed known_hosts) to enforce host identity verification on subsequent connections.
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=no" | |
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=accept-new" |
| return | ||
| fi | ||
| info "Stopping Mindcraft containers on EC2..." | ||
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=no -o ConnectTimeout=5" |
There was a problem hiding this comment.
Stopping the EC2 workloads via ssh with -o StrictHostKeyChecking=no disables host key verification, so a man-in-the-middle can impersonate your instance and receive these administrative commands. While this script currently only stops containers and the instance, using insecure SSH options here normalizes a pattern that can lead to more sensitive operations being MITM'd later. Prefer StrictHostKeyChecking=accept-new or managing known_hosts so that SSH refuses connections when the EC2 host key does not match the expected value.
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=no -o ConnectTimeout=5" | |
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=accept-new -o ConnectTimeout=5" |
| [[ -n "${KEY_FILE:-}" ]] || error "KEY_FILE not set in config.env" | ||
| [[ -f "$KEY_FILE" ]] || error "SSH key not found: ${KEY_FILE}. Run aws/setup.sh first." | ||
|
|
||
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=no -o ConnectTimeout=10" |
There was a problem hiding this comment.
Using ssh with -o StrictHostKeyChecking=no disables host key verification, which allows a man-in-the-middle to impersonate your EC2 instance and run arbitrary commands under the ubuntu user when you run this deploy script. An attacker on the network path could intercept code syncs and remote commands, or trick you into configuring secrets on their host instead of the real server. Switch to StrictHostKeyChecking=accept-new (or pre-populate known_hosts) so the SSH client verifies the EC2 host key on subsequent connections.
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=no -o ConnectTimeout=10" | |
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10" |
| # shellcheck source=/dev/null | ||
| source "$CONFIG_FILE" | ||
| [[ -n "${EC2_IP:-}" ]] || { echo "EC2_IP not set"; exit 1; } | ||
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=no" |
There was a problem hiding this comment.
Here ssh is invoked with -o StrictHostKeyChecking=no, which disables verification of the EC2 host key and makes it possible for a man-in-the-middle to impersonate your instance during backup. An attacker able to intercept this SSH connection could cause backups to run against their own host or observe any data the script might later transmit over this channel. Use StrictHostKeyChecking=accept-new or manage known_hosts explicitly so that SSH refuses connections when the host key changes unexpectedly.
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=no" | |
| SSH_OPTS="-i ${KEY_FILE} -o StrictHostKeyChecking=accept-new" |
01679b6 to
a270f05
Compare
…safety - agent.js: inject [ANTI-LOOP] system message after _forceExplore fires so small models (andy-4:q8_0) cannot loop back to !collectBlocks - dragon_runner.js (death-recovery): ocean escape before wood-collection loop: check for any log within 64 blocks; if none, explore up to 3×200 blocks; fall back to getDiamondPickaxe() if still no trees after 600 blocks - history.js: after each memSaving cycle, cap this.turns at 15 entries to prevent context overflow / instruction collapse on small local models - dragon-slayer.json: sharpen ANTI-STUCK rules (never retry !collectBlocks immediately; use !getDiamondPickaxe for the full chain); add conversation example showing correct response after repeated collect-0 + ANTI-LOOP hint
…ain hardening (#3) * Initial plan * fix: security, correctness, and reliability bugs across 7 files - judge.js: fix timer leak in Promise.race (clear timeout on success and error) - controller.js: wrap getSimilar() in try-catch to prevent crash when ChromaDB goes down - feedback.js: add null check for _client before deleteCollection in error handler - speak.js: use '--' end-of-options for macOS 'say' (consistent with espeak, prevents flag injection) - discord-bot.js: move Gemini API key from URL query param to x-goog-api-key header - dragon_runner.js: add try-catch to death handler, validate coordinates are finite - docker-compose.aws.yml: pin 5 image tags to specific versions instead of :latest Co-authored-by: Z0mb13V1 <201696719+Z0mb13V1@users.noreply.github.com> * fix: revert macOS say to space-prefix guard (say does not support --) Co-authored-by: Z0mb13V1 <201696719+Z0mb13V1@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Z0mb13V1 <201696719+Z0mb13V1@users.noreply.github.com>
…llback - dragon-slayer: redirect all stuck messages to !getDiamondPickaxe (not !explore); add examples covering moveAway-blocked, nav timeout, and collectBlocks-0 cases - skills.js: collectBlocks failure message now points to !getDiamondPickaxe; explore() gains terrain-escape branch (goToSurface + random hop) on consecutive path failures instead of silently breaking; getDiamondPickaxe retries log search with explore(200) before giving up, re-reads inventory to handle mismatched log types - local-research: switch model to sweaterdog/andy-4:F16
…\n- Rewrote getDiamondPickaxe with 4-tier progression (wood→stone→iron→diamond)\n- Added ensureSticksAndTable helper, furnace crafting, iron smelting\n- Added pillarUp and stripMineForOre skills\n- RC29/RC31 auto-redirect: blocked crafting commands → !dragonProgression\n- Blocked actions: craftRecipe, collectBlocks, searchForBlock, getCraftingPlan, newAction\n- RC30 broadened error handler (16+ non-fatal patterns for Baritone noise)\n- craftRecipe unreachable table fallback (place from inventory)\n- digDown MAX_FALL_BLOCKS 2→5, tier 4 sideways relocation\n- dragon_runner.js: RC31 debug tracing, surface recovery for nether portal chunk\n- Profile overhaul: conversation examples, self_prompt, blocked_actions\n- Chunk 1 (diamond_pickaxe) COMPLETE, chunk 2 (nether_portal) in progress"
…ndcraft into pr/hybrid-rig-v0.1.3
| async function callGemini(systemPrompt, userMessage, history = []) { | ||
| if (!GOOGLE_API_KEY) return null; | ||
| try { | ||
| const url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent'; |
There was a problem hiding this comment.
Why don't you just use the google genai client library?
|
This PR is far too bloated to ever be merged. Just include what you need, don't make countless adjustments. And don't include things that don't need to be included, like AWS integration or a discord bot. |
|
[2601.15494] Vibe Coding Kills Open Source Why did you open like 20 different PRs... |
Hybrid Research Rig v0.1.3
A Hybrid Research Rig where two AI bots run simultaneously — one using a cloud ensemble of multiple LLMs (CloudGrok, on AWS EC2), and one using local GPU inference (DragonSlayer, on an RTX 3090) — sharing a persistent Minecraft world on a Paper 1.21.11 server.
12 commits · 149 files changed · +13,320 / −1,065 lines
Key Features
grok-4), and ChromaDB vector memory for past-experience retrievalensureSticksAndTable()helper, furnace crafting, iron smelting, strip-mining, and pillarUp shaft escape!dragonProgressionon its own; agent.js intercepts blocked crafting commands and redirects to the orchestratorpillarUp()for shaft escape,stripMineForOre()for horizontal tunnel mining with wall/ceiling/floor ore detectionWhat This PR Adds
CloudGrok — Cloud Ensemble Bot
A fully autonomous Minecraft bot powered by a voting ensemble of 4 Grok models. On every LLM call:
grok-4,grok-4-fast-non-reasoning,grok-4-1-fast-non-reasoning,grok-code-fast-1grok-4picks the best response (30s timeout, fallback to arbiter)[PAST EXPERIENCE], then logs outcome for future retrievalDragonSlayer — Local GPU Bot
An autonomous Ender Dragon speedrunner running
sweaterdog/andy-4:q8_0via Ollama on an RTX 3090. Features:dragon_progress.jsonagent.jsand redirected to!dragonProgressionorchestratorensureSticksAndTable(), tier-skip logic, furnace crafting, strip-mining, sideways relocationpillarUp()(cobblestone/dirt self-scaffold),stripMineForOre()(1×2 tunnel with 5-face ore detection)Shared Infrastructure
<EC2_PUBLIC_IP>:19565),ONLINE_MODE=FALSE,ENFORCE_SECURE_PROFILE=FALSE:8080with per-bot runtime, goal, and command logTable of Contents
Minecraft Version Compatibility
Server — Java Edition
The server runs Paper with
VERSION: LATEST(currently 1.21.11) and automatically tracks the latest stable Paper release across rebuilds.:19132Result: any Java client from 1.7.4 → latest and any Bedrock client on any current Bedrock version can join. No client-side mods required.
Bots — mineflayer version negotiation
The bots connect using mineflayer with automatic version detection:
mineflayer officially supports up to 1.21.6; with
ENFORCE_SECURE_PROFILE=FALSEon the Paper server it connects cleanly to 1.21.11 without signed-chat rejection.minecraft_versionsetting"auto"✅ (default)"1.20.4"Bedrock Edition — Playing alongside the bots
Bedrock players (Windows, iOS, Android, Console, Xbox) can join the same world the bots are playing in:
<EC2_PUBLIC_IP>19132(UDP — Geyser default)ONLINE_MODE=FALSE)Geyser handles full Java↔Bedrock protocol translation server-side. The bots are unaffected — they connect on the Java TCP port (
19565) and see Bedrock players as normal entities.ViaProxy — Bot-side version bridging (optional)
For cases where the target server runs a version mineflayer doesn't natively support (pre-1.7 or future snapshots), a ViaProxy Docker sidecar is included:
ViaProxy listens on
:25568, auto-detects the target version, and translates. The bot always speaks modern 1.21.x protocol; ViaProxy handles all downward translation.auth-method: NONEworks for offline servers; Microsoft account auth is also supported via the ViaProxy CLI.Full version matrix
19565TCP19565TCP19132UDP25568→19565Commit 1 — Ensemble Decision Engine
Location:
src/ensemble/(6 new files)controller.jsEnsembleModel— drop-in replacement for any single model providerpanel.jsarbiter.jsjudge.jsgrok-4); 30s timeout with arbiter fallbackfeedback.jslogger.jsbots/{BotName}/ensemble_log.jsonIntegration:
EnsembleModelimplements the samesendRequest(turns, systemMessage)interface as every other model class, soprompter.jsuses it as a transparent drop-in whenprofile.modelis"ensemble".Commit 2 — Ender Dragon Automation, RC13–RC31 Skills, Baritone Pathfinding
Ender Dragon Automation
Location:
src/agent/library/dragon_runner.js(1589 LOC) +dragon_progress.js(359 LOC)getDiamondPickaxe()buildNetherPortal()collectBlazeRods()collectEnderPearls()locateStronghold()defeatEnderDragon()Orchestrator: loads persistent state on start, 5 retries per chunk with exponential backoff, death recovery (return to drop coords, re-craft lost tools), dimension-aware. Atomic state writes to
dragon_progress.json.getDiamondPickaxe — 4-Tier Rewrite (RC29–RC31)
The
getDiamondPickaxe()function was completely rewritten across RC29–RC31 to handle the specific limitations of theandy-4:q8_0model:ensureSticksAndTable()→ craft wooden pickaxe. Skip if already have cobblestone + sticks.stripMineForOre()at y=16 → smelt with furnace → craft. Auto-crafts furnace (8 cobblestone), finds fuel (coal/planks).stripMineForOre()at y=-58 → craft. Sideways cardinal relocation on retry (no goToSurface). Perpendicular strip-mine fallback.MAX_FALL_BLOCKS= 5 for cave gaps.Helper:
ensureSticksAndTable()— ensures 4+ sticks and a reachable crafting table (distance ≤ 4 blocks). Places table from inventory if navigation fails. Converts logs→planks if plank shortage.Baritone A* Pathfinding (RC25+)
patches/@miner-org+mineflayer-baritone+4.5.0.patch+world.js+skills.js:dist × 1s + 10s, min 20s)isClearPath()temporarily disables break/place to test feasibilityisWalkableto preventboundingBoxcrash on respawnSkills RC13–RC31
safeToBreakfilter rejecting tree logs + log-type fallbackcollectBlock: retry on "Digging aborted" from combat, exclude failed positionsbot.collectBlock.collect()for Paper compatibilitygoToPosition(15s),dig(10s),pickup(8s)getDiamondPickaxe4-tier rewrite,ensureSticksAndTable(), tier-skip logicpillarUp(),stripMineForOre(), broadened error handler (16+ non-fatal patterns),MAX_FALL_BLOCKS2→5!dragonProgression, furnace crafting + iron smelting, craftRecipe unreachable table fallback, debug tracing, surface recoveryCommit 3 — Vision System, HUD Overlay, Discord Bot
Vision System
import()for camera module — graceful fallback if WebGL/canvas unavailableLIBGL_ALWAYS_SOFTWARE=1)grok-2-vision-1212for CloudGrok)HUD Overlay (
mindserver.js+public/index.html):8080Discord Bot (
discord-bot.js, 1130 LOC)!start,!stop,!restartwith group-based controlDISCORD_ADMIN_IDSfor privileged commands!usage [agent|all]shows token/cost statsCommit 4 — Security Hardening
src/utils/message_validator.jssrc/utils/rate_limiter.jssrc/utils/usage_tracker.jssrc/utils/keys.jskeys.json;.envsupportsrc/agent/speak.jssrc/agent/commands/index.jsisCommandBlocked()against per-profileblocked_actionsarraysettings.jsdeepSanitize()strips__proto__,constructor,prototypefromSETTINGS_JSONoverridesdiscord-bot.jsDockerfileCommit 5 — AWS / Docker Infrastructure
Docker / Compose
docker-compose.aws.yml: production config with LiteLLM proxy (:4000), ChromaDB, Tailscale sidecar,ENFORCE_SECURE_PROFILE=FALSE(required for mineflayer unsigned chat on Paper 1.19.1+)docker-compose.yml: dev compose with Ollama host routing, port19565(was25565)Dockerfile: non-root user, Xvfb/Mesa for vision, memory 1536M → 2560MTasks.Dockerfile: separate image for task evaluation runnerAWS Scripts (
aws/)ec2-go.shsetup.shdeploy.shec2-deploy.shbackup.sh/restore.shenv-toggle.shsetup-ollama-proxy.shObservability
prometheus-aws.yml: Prometheus scrape config for EC2grafana-provisioning/: dashboards, datasources, and alerting rulesServer Security
whitelist.json: pre-built offline UUIDs (avoids Playerdb API crash forONLINE_MODE=FALSEbot names)19565(non-default, external); internal remains25565ENFORCE_SECURE_PROFILE=FALSE: Paper 1.19.1+ requires cryptographically signed chat; mineflayer sends unsigned packets which are silently dropped without this flagCommit 6 — Profiles, Core Agent, Model Providers, Config
New Profiles
ensemble.jsongrok-4judgecloud-persistent.jsongrok-4dragon-slayer.jsonsweaterdog/andy-4:q8_0via Ollamalocal-research.jsonsweaterdog/andy-4via OllamaCore Agent Improvements
agent.js: death handler + respawn recovery, post-respawn grace period (5s), human-player message priority, max-command cap at 15action_manager.js: deadlock detection,cancelResume(), improved error propagationmodes.js: night bed mode, door navigation preference, anti-team-kill guards, food panic spiral preventionhistory.js/learnings.js: atomic writes (.tmp+rename), EBADF retry with exponential backoffagent_process.js: 3 quick-exit retries with increasing delayconversation.js: inter-bot messaging protocol; alias system (/msg gk→Grok_En)Model Providers
prompter.js:$WIKI,$LEARNINGS,$MEMORY,$INVENTORY,$STATSplaceholder injectiongrok.js: updated for grok-4 / grok-4-fast-non-reasoning APIollama.js: switched tohttp.request(avoids headers timeout),num_ctx/num_gpuparamsConfig / Tooling
settings.js:deepSanitize(),SETTINGS_JSONenv override,allow_vision, port19565eslint.config.js: flat config migration; zero-warning enforcement.husky/pre-commit: lint gate on every commitdata/minecraft_wiki.json: wiki data for$WIKIprompt injectionCLAUDE.md: AI assistant guidance for codebase navigationCommits 7–12 — RC29–RC31 DragonSlayer Fixes
These 6 commits represent iterative debugging and stabilization of the DragonSlayer bot during live testing on the EC2 server.
Commit 7 — Repetition Guard & Self-Prompt Safety
Commit 8 — Anti-Stuck Routing & Terrain Escape
getDiamondPickaxelog fallbackCommit 9 — CI/CD Workflows
Commit 10 — Copilot Code Review Fixes
Commit 11 — RC31: Full DragonSlayer Overhaul
The largest single change — complete rewrite of the DragonSlayer pipeline:
skills.js(+552 lines):getDiamondPickaxe()4-tier rewrite withensureSticksAndTable()helperpillarUp(bot, distance)— cobblestone/dirt self-scaffold to escape shaftsstripMineForOre(bot, oreNames, length)— 1×2 horizontal tunnel with 5-face ore detectioncraftRecipe()unreachable table fallback — places crafting_table from inventorydigDown()MAX_FALL_BLOCKSincreased from 2 to 5agent.js(+25 lines):!craftRecipe,!collectBlocks,!searchForBlock,!getCraftingPlan,!newAction) is detected, agent automatically executes!dragonProgressioninsteadandy-4:q8_0never generates!dragonProgressionon its owninit_agent.js(+34 lines):NON_FATAL_PATTERNSisNonFatal(msg)helper catches Baritone pathfinder noise, navigation timeouts, connection resetsdragon_runner.js(+46 lines):[RC31]console.log markers) throughout prepareForChunk, orchestration loop, chunk runner, buildNetherPortaldragon-slayer.json(profile overhaul):blocked_actions:["!startConversation", "!moveAway", "!craftRecipe", "!collectBlocks", "!searchForBlock", "!getCraftingPlan", "!newAction"]!dragonProgressionCommit 12 — Merge Commit
Breaking Changes
.envfile now required for API keys (previouslykeys.jsononly)allow_insecure_codingdefaults tofalse—!newActionblocked unless explicitly enabledblocked_actions,conversation_examples, mode configs) — old profiles load but won't use new features25565to19565Test Plan
Manually Tested
:8080ENFORCE_SECURE_PROFILE=FALSEallows mineflayer bot chat to appear in-game!dragonProgressionec2-go.shworksIn Progress
Automated
Suggested Community Testing
!beatMinecraftfrom a fresh worldCopilot Review Responses
Tasks.Dockerfilegit clonepulls unpinned HEADsrc/mindcraft/mindcraft.jsagent_namein/tmppath unsanitizedpath.basename()sanitization added.src/agent/conversation.jsendAllConversations()async but doesn't awaitasynckeyword.src/agent/library/world.jsisClearPath()assumesbot.ashfinderexistsbot.ashfinder?.confignull-guard with fallback.src/agent/commands/index.jsdelete commandList.find(...)doesn't remove from arrayisCommandBlocked()at execution time; vestigialdeletecleaned up.src/agent/vision/vision_interpreter.jscapture()guards onthis.camera?.ready.eslint.config.jsno-undefbugscoder.js).Tasks.DockerfileHow to Review
Suggested order for a large PR:
src/ensemble/(6 files) andsrc/agent/library/dragon_runner.js/dragon_progress.js. Self-contained, don't modify existing code.docker-compose.aws.ymlplugin list,ENFORCE_SECURE_PROFILEflag,settings.jsminecraft_version: "auto".src/utils/message_validator.js,rate_limiter.js,settings.js(deepSanitize). Small, focused files.agent.js,action_manager.js,modes.js. These modify existing behavior.skills.jsis the largest diff (+552 lines in RC31 alone). The RC13–RC31 changes are incremental, each with a clear commit message.docker-compose*.yml,Dockerfile,aws/scripts. Review for correctness and security.Files that can be skimmed or skipped:
README.md(docs only),discord-bot.js(additive, doesn't touch core),start.ps1(Windows convenience script),CLAUDE.md(AI assistant guidance).