cf1f895b2529642fee896e330cc055809503a6b7
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
86e5294bb8 |
chore: snapshot pre-v0.2.0 WIP (pathfinder/reflex/metrics/skills improvements)
Baseline for the v0.2.0 self-learning iteration. All 205 tests pass on this state. Subsequent commits in this branch layer the knowledge base, post-mortem coach, and persona narration on top. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
ae7b4d89cb |
feat(runtime): early-game survival curriculum + stone/craft skills (Phase 3) (#15)
Phase 3 of plans/autonomous-survival-bot-prd.md. Gives the bot a
deterministic path from empty inventory through stone-tier tools and
basic storage, without an LLM call per tick.
New:
- runtime/curriculum.js: ordered milestone chooser
(wood.16 → wood.planks-and-sticks → wood.tools → stone.32 →
stone.tools → food.basic → storage.chest → shelter.torch). Each
milestone exposes isDone(inventory, snapshot) and suggest() returning
a { skillId } plan the scheduler can dispatch via runSkill. isDone
uses "stage reached" escapes so progress is monotonic — crafting
planks doesn't bounce the chooser back to "gather 16 logs".
- runtime/skills/gather-stone.js: gather.stone with pickaxe-required
precondition, blacklist on failed paths, registry-aware matching
(stone / cobblestone / deepslate / cobbled_deepslate / andesite /
diorite / granite).
- runtime/skills/craft.js: factory + concrete skills for craft.planks,
craft.sticks, craft.wooden-axe/-pickaxe/-sword, craft.stone-axe/
-pickaxe/-sword, craft.furnace, craft.chest, craft.torch (torch
requires coal or charcoal preflight).
Tests:
- runtime/curriculum.test.js: 14 tests covering chooser ordering,
per-milestone skill suggestion, inventoryFull threshold, monotonic
advancement across stage transitions.
- npm test now runs the full suite: 28/28 passing.
Wiring:
- runtime/bot.js: lastSnapshot.curriculum carries the next milestone
+ suggested skill on every tick; lastSnapshot.currentMilestone
prefers the curriculum title over the planner.md line.
- tui/tui.tsx: milestone line shows the curriculum's suggested skill
and an [inventory full] flag when isInventoryFull fires.
Reflex.js still calls actions.js directly; wiring the scheduler to
runSkill(plan.skillId, …) lands in Phase 4.
Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
f301529f42 |
feat(runtime): observability + no-progress detector (Phase 1) (#13)
Phase 1 of plans/autonomous-survival-bot-prd.md. The bot must always be able to answer "what am I doing and why am I not doing more?" without parsing the log stream. New modules: - runtime/state.js: pure FSM classifier emitting emergency / working / recovering / planning / social / idle from snapshot + reflex context. - runtime/no-progress.js: sliding-window detector that watches position and inventory; when both are unchanged for 60 s+, emits one stable reason code from REASONS (waiting_for_day, night_hostile_nearby, no_food_source, inventory_full, no_reachable_target, planner_empty, awaiting_action_cooldown). - runtime/viewer.js: optional prismarine-viewer launcher behind VIEWER_PORT. Lazy import so the dep is not required by default. Wiring: - runtime/bot.js: tick() now computes runtimeState + noProgressReason every tick and stamps them on the snapshot along with activeSkill, currentMilestone (read from plan.md, cached 30 s), lastResult, failuresByCode and lastEscalation. - runtime/bot.js: dispatchAction records lastResult and lastFailureAt for the recovering-state classifier. - runtime/planner.js: exports isPlannerBusy(), readNextMilestone() and planExists() so the runtime can show planning state + current milestone without spawning extra Pi calls. - runtime/config.js: adds VIEWER_PORT support. TUI: - tui/tui.tsx: StatusBar gains a state badge, current-skill row, milestone row, no-progress reason warning, last-result line with ok/fail color, failures-by-class summary and last-escalation age. Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
f5361ad9a4 |
feat(runtime): autonomous reflex — chop wood + wander + proactive movement (#8)
Closes the "bot stands on a tree doing nothing" problem reported live when the operator launched the TUI after PR #6 landed. The reactive chain (operator > defend > eat > sleep > idle) was passive by design: day-time, full HP and food, no hostile within 4 m ⇒ every reflex returned noop. The bot perched in dark-oak canopy and never moved. Changes runtime/actions.js: - chopNearestTree: find any *_log within 32 blocks, equip best axe (falls back to fists), path to the block, dig. Per-bot 5-min blacklist of unreachable log positions so we don't grind on the same impossible target. - wander: pick a random offset 6-16 blocks away and path there. - setMovementsForGather / setMovementsForTravel: every action that uses pathfinder now sets its own Movements profile (canDig=true) instead of inheriting whatever the previous caller left. The old behaviour caused chop to inherit flee's canDig=false and get stuck in the canopy. - fleeFrom now uses canDig=true too — the user observed the bot permanently stuck on a leaf block because escape required digging. runtime/reflex.js: - new autonomousReflex between sleep and idle. Cooldown 10s. Picks chop when log count < 16, else wander. When chop reports "no reachable log within 32 blocks" we switch to wander for 60s so we don't re-fire chop against the same impossible position. - defendReflex tightened: only flee when closest is ≤8m (or ≤12m on low HP). Avoids the "82 distant hostiles ⇒ constant flee loop" pathology observed at this spawn. - flee cooldown: same mob name within 60s ⇒ noop, so we yield to other reflexes if flee keeps timing out. - sleepReflex retry cooldown raised 30s → 5min. Sleeping fails permanently if no bed is around; the short retry blocked autonomous behaviour every tick. - ctx.lastReflex now records {name, label, ts} after each dispatched/completed reflex so the TUI can show what the bot just decided. runtime/bot.js: - per-tick snapshot adds lastReflex and busy fields for the TUI. - maybeReplyToPlayer: light canned greetings (yo/hey/hi/привет) to non-operators when they address the bot. 30s cooldown so we don't spam. tui/tui.tsx: - status bar shows either "▸ busy: <label>" while an action is in flight, or "last reflex: <name> (<label>) Ns ago" when idle. Gives an at-a-glance answer to "what is the bot doing right now?" Smoke-tested live (play.xmatic.team, 2026-05-25T13:30-13:39): - bot did dispatch chop tree (oak_log at 617,82,95) - real bug surfaced and 3-fail rule filed a proposal automatically - after the runtime fix, chop returns "no reachable log" gracefully - bot switched to wander on the next tick - position moved from (623.31, 85, 95.12) to (623.41, 86.02, 96.7) — the first observable movement in this dark-oak spawn Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
cd14bbf89a |
feat(runtime): state persistence + proposals + supervisor hot-restart (#6)
Closes the self-improvement loop end-to-end:
reflex fails 3× → proposal file → operator approves in TUI →
`npm run propose:apply <file>` spawns Pi on a feature branch →
Pi commits the patch → supervisor watches runtime/*.js and
restarts the child on change.
runtime/state-store.js — atomic current-task.json writes, daily diary
append, proposals/ + proposals/approved/ helpers.
runtime/bot.js:
- ctx.dispatch writes current-task.json on start and updates it on
completion / failure / throw.
- failure tracker: 3 consecutive same-label failures → writeProposal()
with the snapshot, labels, and a suggested-next-step section.
30-min cooldown prevents proposal spam.
- on startup, surfaces resume info (previous task + pending proposal
count); on death, clears current-task.json + writes diary line.
- new IPC commands: PROPOSAL_LATEST returns the newest pending
proposal body; PROPOSAL_APPROVE moves it to proposals/approved/.
tui/tui.tsx — status bar shows `[proposals N, press y]` badge when
bot.pendingProposals > 0. Hotkey 'y' opens the proposal panel; 'y'
approves, 'n'/Esc closes.
scripts/propose-apply.js — given an approved proposal filename, creates
a `feat/proposal-<slug>` branch and spawns `pi -p` with the proposal
+ repo-conventions prompt. Refuses on dirty tree. No auto-push, no
auto-merge — operator reviews the diff and decides.
runtime/supervisor.js — forks bot.js as a child, watches runtime/*.js,
restarts on file change or on child exit code 42. Rate-limited at 5
restarts/minute. SIGINT/SIGTERM forward cleanly. `npm run bot` now
goes through the supervisor; `npm run bot:bare` skips it.
Smoke-tested: supervisor spawned, bot connected to MC, spawned at
expected coords, diary line written, state cleanup on SIGTERM correct.
Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|
|
1e3b36a9a1 |
feat(runtime): hybrid script reflex + Ink TUI + Pi-on-demand escalation (#4)
* fix(mindcraft-skills): hard timeout on every skill call mc_avoid_enemies (and 7 other tools) wrapped only in safeCall without a withTimeout. When mindcraft's underlying pathfinder/pvp goal couldn't be satisfied, the call never resolved — the Pi tick loop blocked forever. Observed live: mc_avoid_enemies pending >10 minutes after one mc_observe. safeCall now takes timeoutMs (default 30s) and wraps withTimeout itself, so every tool gets a hard ceiling. Per-tool overrides: - goToPosition / goToNearestBlock: 120s / 90s (unchanged from before) - defendSelf / avoidEnemies: 45s - stay: secs*1000 + 10s - craft / consume / pickup / place: 30s - equip: 15s collectBlock still uses its bespoke per-iter 75s loop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(runtime): script-driven reflex daemon + Ink TUI dashboard Pure-Pi runtime had three failure modes in practice: - slow: 20-60s per decision because LLM was in the hot path - expensive: every tick (defend, eat, idle) paid for a reasoning pass - invisible: required tmux capture-pane to know what the bot was doing New runtime/ layer is a long-running Node daemon that owns the MC connection, ticks a priority-ordered reflex chain (defend > eat > sleep > idle) with NO LLM in the hot path, and exposes status + commands over a Unix-socket IPC. tui/ is an Ink dashboard that attaches over IPC and can detach freely — multiple TUI clients can connect at once. Pi/Codex are still available, but as on-demand escalation: TUI hotkey 'a' spawns `pi -p "<prompt>"` as a subprocess and streams stdout into the dashboard. The self-improvement loop (proposals → operator approval → Pi-driven patch → hot reload) is documented in docs/runtime.md but not yet wired. Reflex bodies are stubs today — they log decisions but don't drive Mineflayer actions yet. The priority chain, IPC contract, and TUI are fully working; subsequent commits will fill in defend/eat/sleep bodies and wire automatic escalation. Run with `npm run bot` + `npm run tui`. Pi-only fallback stays at `npm run agent`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |