Commit Graph

3 Commits

Author SHA1 Message Date
7217e3553b feat(redstone): wiki_recipe_image — composite real recipe PNG and upload
Previous wiki_recipe only returned the page thumbnail, so "send me the
recipe image" delivered a picture of the item, not the recipe itself.
minecraft.wiki renders recipes as live HTML grids, not standalone PNGs,
so we now generate the image ourselves.

mcp/lib/minecraft-wiki-tools.ts:
- parseCraftingGrid(html): pulls the 3×3 input grid + result item URL
  from <span class="mcui mcui-Crafting_Table">. Each <span class="invslot">
  is either empty (chunk starts with </span>) or has an <img src="/images/
  Invicon_X.png?h">. Reading-order chunks → grid; first non-null after
  the 9th input slot → result.
- composeRecipePng(grid, result): fetches each unique sprite, resizes
  to 64×64 via sharp (nearest-neighbour to keep pixel art crisp),
  composites onto a #8b8b8b inventory-style background with #6f6f6f
  slot squares + dark borders, places an SVG-rendered "→" arrow,
  then the result cell next to it. PNG buffer returned.
- New tool wiki_recipe_image(title, chat, caption?) that runs the
  pipeline end-to-end and uploads via tg.sendPhotoBytes — one tool
  call, image already in the chat when it returns.

mcp/lib/types.ts:
- TgClient gains sendPhotoBytes({ chat_id, bytes, filename?, caption?,
  parse_mode?, reply_to_message_id? }). Multipart/form-data POST to
  sendPhoto, since Telegram's URL-mode can only fetch public URLs and
  the composited PNG only lives in memory. 30s timeout (vs the 20s on
  the JSON call) because uploads are bigger.

mcp/package.json + bot/package.json: add sharp ^0.33.5. mcp/ pulls it
in too so /mc/mcp/lib resolves it at the bot's runtime (the bot's
node_modules is at /app while the lib files live at /mc/mcp/lib).

Persona prompt: wiki_recipe_image is now the FIRST call for any
"recipe" / "send me the recipe image" request. Single tool turn ends
with the photo already in the chat. wiki_recipe stays as a fallback
when the page has no 3×3 crafting widget (smelting / brewing / smithing
use different mcui classes).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 23:54:20 +02:00
cab5337e3f stream Redstone replies via sendMessageDraft + fix self-killing server_down
Two related changes to how Redstone behaves in chat.

Streaming: replies now animate word-by-word into Telegram using the new
sendMessageDraft endpoint (Bot API 9.5, March 2026) via the @grammyjs/stream
plugin, with @grammyjs/auto-retry on the API layer to swallow 429s
transparently. The previous editMessageText-based approach is gone —
sendMessageDraft is designed for this and animates natively on the client
without hitting the 1/sec-per-chat edit limit. Pace lives in
STREAM_WORD_DELAY_MS=50; tunable in one spot.

server_down footgun: the MCP tool was running `compose down` with no
service arg, which tore down the whole project — including the bot
container running the tool call, which then got SIGTERM mid-conversation
and didn't come back (unless-stopped doesn't restart on a clean compose
down). Behaviour now matches the existing /stop slash command:
compose stop minecraft autossh, leaving the bot up. Pass an explicit
service to stop just that one.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 08:47:35 +02:00
9ac3705d5e add telegram bot and autossh tunnel 2026-05-11 21:51:59 +02:00