feat(recovery): death handler + auto-defend reflex + bulk-collect rework + mc_stay shim
Four targeted fixes for issues observed during the live autonomous test:
1. **bot.modes shim** (extensions/lib/mcdata.js)
Mindcraft skills.* call bot.modes.pause('cowardice') in 7+ places.
`mineflayer-modes` does not exist on npm — it's internal to Mindcraft.
attachPluginsAndInit now installs a no-op shim so skills.stay() /
.consume() / .defendSelf() etc. stop crashing with "pause undefined".
2. **Death + respawn handlers** (extensions/mineflayer-bridge.ts)
Subscribe to bot 'death' event: append diary line with position,
clear current-task.json so Pi doesn't resume a stale task referencing
inventory that no longer exists.
On 'spawn' within 5s of death: log the new respawn position to diary.
Live test had bot killed twice by zombies at night; the next Pi
prompt was unable to recover. With this it's now an explicit diary
line + clean task slate.
3. **Auto-defend reflex tick** (extensions/mineflayer-bridge.ts)
New setInterval(2s) that, when bot.health < 18 AND a hostile mob
(zombie/skeleton/creeper/spider/etc.) is within 6 blocks AND no
active world task, fires `bot.pvp.attack(nearest)` in the background.
No LLM call needed for instant self-defense — saves tokens and reacts
on mineflayer timescale (sub-second) rather than Pi loop timescale
(~10s+ to reason and dispatch). Throttled to once per 4s.
4. **mc_collect_block bulk rework** (extensions/mindcraft-skills.ts)
Live test showed count=1 succeeds in ~25s but count=8 hangs past
270s with identical blocks in range. Upstream collectBlock plugin
appears to drift on its block cache after the first dig in dense
terrain. Loop single-block collects in-tool instead (75s per iter,
re-pathfind on each iteration). Track per-iter success/failure,
abort after 3 consecutive failures, return aggregate count to the
agent so it can adapt instead of seeing a single failure.
Smoke test: both extensions load, bot connects, perception confirms
hostiles nearby and daylight safety check. No syntax/runtime errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -268,14 +268,45 @@ export default async function mindcraftSkills(pi: ExtensionAPI) {
|
||||
async execute(_id, params: { blockType: string; count?: number }) {
|
||||
const bot = getBot();
|
||||
const count = Math.max(1, Math.min(64, Math.floor(params.count ?? 1)));
|
||||
// Timeout scales with count: ~30s per block plus 30s overhead.
|
||||
// Allows count=8 (about 4 min) without hanging forever on
|
||||
// pathfinder-unreachable cases.
|
||||
const timeoutMs = Math.min(600_000, 30_000 + count * 30_000);
|
||||
const ok = await safeCall("collectBlock", () =>
|
||||
withTimeout(skills.collectBlock(bot, params.blockType, count), timeoutMs, `collectBlock(${params.blockType}, ${count})`),
|
||||
// Bulk collection in dense terrain reliably times out on the
|
||||
// upstream mineflayer-collectblock plugin (observed live: count=1
|
||||
// works in ~25s, count=8 hangs past 270s with the same blocks
|
||||
// in range). Loop single-block collects instead — each iteration
|
||||
// re-pathfinds from the bot's current position, which is robust
|
||||
// to the block-cache and pathfinder drift problems that cause
|
||||
// the hangs. Per-iter timeout 75s.
|
||||
let collected = 0;
|
||||
let consecutiveFails = 0;
|
||||
const errors: string[] = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
try {
|
||||
const ok = await withTimeout(
|
||||
skills.collectBlock(bot, params.blockType, 1),
|
||||
75_000,
|
||||
`collectBlock(${params.blockType}) iter ${i + 1}/${count}`,
|
||||
);
|
||||
if (ok) {
|
||||
collected++;
|
||||
consecutiveFails = 0;
|
||||
} else {
|
||||
consecutiveFails++;
|
||||
errors.push(`iter ${i + 1}: returned false`);
|
||||
}
|
||||
} catch (e: any) {
|
||||
consecutiveFails++;
|
||||
errors.push(`iter ${i + 1}: ${e?.message ?? String(e)}`);
|
||||
}
|
||||
if (consecutiveFails >= 3) {
|
||||
return textResult(
|
||||
`Collected ${collected}/${count} ${params.blockType}; aborted after 3 consecutive failures. Last errors: ${errors.slice(-3).join("; ")}`,
|
||||
{ collected, requested: count, errors: errors.slice(-3) },
|
||||
);
|
||||
}
|
||||
}
|
||||
return textResult(
|
||||
`Collected ${collected}/${count} ${params.blockType}${errors.length ? ` (${errors.length} iters failed but recovered)` : ""}.`,
|
||||
{ collected, requested: count, errors },
|
||||
);
|
||||
return textResult(ok ? `Collected ${count} of ${params.blockType}.` : `collectBlock returned false for ${params.blockType}.`, { ok, blockType: params.blockType, count });
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user