924f16b9da
New tools implemented and deployed to dev gateway: - log.query: focused event queries (chat/deaths/joins/actions), replaces 200-line dump - user.ask: risk-scaled clarifying questions, async with tellraw - journal.read/write: per-player files, cross-mode (God+Sudo share) All wired into langgraph_gateway.py _execute_tool and model-driven tool loop. Tool schemas updated (22 total). Deployed to CT 644 dev server. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
972 lines
37 KiB
Python
972 lines
37 KiB
Python
"""
|
|
Tool schemas for the Minecraft AI God model.
|
|
|
|
Defines all tools the model can call during inference, plus common RCON error
|
|
patterns used for generating error-correction training data.
|
|
|
|
Exports:
|
|
TOOL_SCHEMAS — Python list of dicts (name, description, parameters in JSON Schema)
|
|
QWEN3_TOOLS — Same tools formatted for Qwen3 chat template
|
|
RCON_ERROR_PATTERNS — Dict mapping RCON error substrings to correction metadata
|
|
"""
|
|
|
|
from typing import List, Dict, Any
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Tool definitions (canonical source of truth)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
TOOL_SCHEMAS: List[Dict[str, Any]] = [
|
|
{
|
|
"name": "rcon.execute",
|
|
"description": (
|
|
"Execute a Minecraft command via RCON on the server. "
|
|
"Returns whether the command succeeded and the server's response text. "
|
|
"Commands should NOT start with a leading slash."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"command": {
|
|
"type": "string",
|
|
"description": "The Minecraft command to execute (no leading slash)."
|
|
}
|
|
},
|
|
"required": ["command"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"success": {"type": "boolean"},
|
|
"result": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "minecraft.wiki_lookup",
|
|
"description": (
|
|
"Look up command syntax, item info, or game mechanics from the "
|
|
"Minecraft Wiki. Use this when you are unsure about exact syntax, "
|
|
"item IDs, enchantment names, effect names, or entity types."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {
|
|
"type": "string",
|
|
"description": "The search query (e.g. 'give command syntax', 'trident enchantments')."
|
|
}
|
|
},
|
|
"required": ["query"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"content": {"type": "string"},
|
|
"url": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "plugin.docs_lookup",
|
|
"description": (
|
|
"Look up plugin command syntax and documentation for server plugins: "
|
|
"WorldGuard, WorldEdit/FAWE, CoreProtect, EssentialsX, LuckPerms. "
|
|
"Use this when unsure about plugin-specific command syntax, flags, "
|
|
"parameters, or configuration options."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"plugin": {
|
|
"type": "string",
|
|
"enum": ["worldguard", "worldedit", "coreprotect", "essentialsx", "luckperms"],
|
|
"description": "Which plugin to look up docs for."
|
|
},
|
|
"query": {
|
|
"type": "string",
|
|
"description": "What to search for (e.g. 'region flags', 'rollback syntax', 'group inheritance')."
|
|
}
|
|
},
|
|
"required": ["plugin", "query"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"content": {"type": "string"},
|
|
"url": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "minecraft.changelog_lookup",
|
|
"description": (
|
|
"Look up what changed in a specific Minecraft version. Use this to check "
|
|
"if a feature, item, or command exists in the current version (1.21), "
|
|
"when something was added or removed, or what changed between versions."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"version": {
|
|
"type": "string",
|
|
"description": "Version to look up (e.g. '1.21', '1.20.4', '1.19'). Omit for latest."
|
|
},
|
|
"query": {
|
|
"type": "string",
|
|
"description": "What to search for in the changelog (e.g. 'mace', 'copper', 'trial chambers')."
|
|
}
|
|
},
|
|
"required": ["query"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"content": {"type": "string"},
|
|
"version": {"type": "string"},
|
|
"url": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "paper.docs_lookup",
|
|
"description": (
|
|
"Look up Paper server-specific documentation — API differences from Spigot, "
|
|
"Paper-specific configuration, async chunk loading, and server optimization. "
|
|
"Use when behavior differs from vanilla or Spigot."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {
|
|
"type": "string",
|
|
"description": "What to search for (e.g. 'async chunks', 'paper-world config', 'timings')."
|
|
}
|
|
},
|
|
"required": ["query"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"content": {"type": "string"},
|
|
"url": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "world.player_info",
|
|
"description": (
|
|
"Get a player's current state including health, position, and a "
|
|
"summary of their inventory. Requires the player to be online."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"player": {
|
|
"type": "string",
|
|
"description": "The player's in-game name (case-sensitive)."
|
|
}
|
|
},
|
|
"required": ["player"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"health": {"type": "number"},
|
|
"position": {
|
|
"type": "object",
|
|
"properties": {
|
|
"x": {"type": "integer"},
|
|
"y": {"type": "integer"},
|
|
"z": {"type": "integer"}
|
|
}
|
|
},
|
|
"inventory_summary": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "world.server_state",
|
|
"description": (
|
|
"Get the current server state: time of day, weather, online players, "
|
|
"and world border size. No parameters required."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {},
|
|
"required": [],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"time_of_day": {"type": "string"},
|
|
"weather": {"type": "string"},
|
|
"online_players": {
|
|
"type": "array",
|
|
"items": {"type": "string"}
|
|
},
|
|
"world_border": {"type": "number"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "world.nearby_entities",
|
|
"description": (
|
|
"Scan for entities near a player within a given radius. "
|
|
"Returns a list of entity types, counts, and distances. "
|
|
"Use this before kill/target commands to know what's around the player."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"player": {
|
|
"type": "string",
|
|
"description": "The player to scan around (case-sensitive)."
|
|
},
|
|
"radius": {
|
|
"type": "integer",
|
|
"description": "Search radius in blocks (default 32, max 128)."
|
|
}
|
|
},
|
|
"required": ["player"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"entities": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"type": {"type": "string"},
|
|
"count": {"type": "integer"},
|
|
"nearest_distance": {"type": "number"}
|
|
}
|
|
}
|
|
},
|
|
"total": {"type": "integer"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "memory.read",
|
|
"description": (
|
|
"Read saved memories for a player — locations, preferences, and facts. "
|
|
"Use this when a player references a saved location (e.g. 'tp me home') "
|
|
"or asks what you know about them."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"player": {
|
|
"type": "string",
|
|
"description": "Player whose memories to read (omit for requesting player)."
|
|
},
|
|
"key": {
|
|
"type": "string",
|
|
"description": "Specific memory key to look up (e.g. 'home', 'base'). Omit to get all."
|
|
}
|
|
},
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"memories": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"key": {"type": "string"},
|
|
"type": {"type": "string"},
|
|
"value": {}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "memory.write",
|
|
"description": (
|
|
"Save a memory for a player — a named location, preference, or fact. "
|
|
"Use this when a player asks you to remember something."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"player": {
|
|
"type": "string",
|
|
"description": "Player who owns this memory."
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["location", "preference", "fact"],
|
|
"description": "Memory type."
|
|
},
|
|
"key": {
|
|
"type": "string",
|
|
"description": "Memory name (e.g. 'home', 'base', 'favorite_tool')."
|
|
},
|
|
"value": {
|
|
"description": "Memory data — {x,y,z} for locations, string for others."
|
|
}
|
|
},
|
|
"required": ["player", "type", "key", "value"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"},
|
|
"key": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
# ── Script environment tools ──────────────────────────────────────────
|
|
{
|
|
"name": "script.write",
|
|
"description": (
|
|
"Write a mcfunction script to the Mortdecai datapack. Each line is one "
|
|
"Minecraft command (no leading slash). Use relative coordinates (~) for "
|
|
"position-relative builds. Scripts are stored at "
|
|
"mortdecai:functions/<name>.mcfunction. Overwrites if the script already exists."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Script name (e.g. 'build_house', 'arena_setup'). Lowercase, underscores."
|
|
},
|
|
"commands": {
|
|
"type": "array",
|
|
"items": {"type": "string"},
|
|
"description": "List of Minecraft commands, one per line. No leading slash."
|
|
},
|
|
"description": {
|
|
"type": "string",
|
|
"description": "Comment at the top of the file describing what this script does."
|
|
}
|
|
},
|
|
"required": ["name", "commands"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"},
|
|
"path": {"type": "string"},
|
|
"lines": {"type": "integer"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "script.validate",
|
|
"description": (
|
|
"Validate a list of commands without writing or executing. Dry-runs each "
|
|
"command through RCON and reports errors. Use this before script.write to "
|
|
"catch mistakes. Returns per-line pass/fail results."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"commands": {
|
|
"type": "array",
|
|
"items": {"type": "string"},
|
|
"description": "List of Minecraft commands to validate."
|
|
}
|
|
},
|
|
"required": ["commands"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"valid": {"type": "boolean"},
|
|
"total": {"type": "integer"},
|
|
"passed": {"type": "integer"},
|
|
"errors": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"line": {"type": "integer"},
|
|
"command": {"type": "string"},
|
|
"error": {"type": "string"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "script.execute",
|
|
"description": (
|
|
"Execute a previously written mcfunction script. Optionally run it as/at "
|
|
"a specific player for correct relative coordinates."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Script name to execute (e.g. 'build_house')."
|
|
},
|
|
"as_player": {
|
|
"type": "string",
|
|
"description": "Run the script as this player (for ~ coordinates). Optional."
|
|
}
|
|
},
|
|
"required": ["name"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"},
|
|
"result": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "script.read",
|
|
"description": (
|
|
"Read the contents of an existing mcfunction script. "
|
|
"Use this to review or debug a script before modifying it."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Script name to read."
|
|
}
|
|
},
|
|
"required": ["name"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"},
|
|
"commands": {
|
|
"type": "array",
|
|
"items": {"type": "string"}
|
|
},
|
|
"lines": {"type": "integer"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "script.list",
|
|
"description": (
|
|
"List all scripts in the Mortdecai datapack. Returns script names, "
|
|
"line counts, and whether they are scheduled (tick/load)."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {},
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"scripts": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {"type": "string"},
|
|
"lines": {"type": "integer"},
|
|
"scheduled": {"type": "string", "description": "tick, load, or none"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "script.delete",
|
|
"description": (
|
|
"Delete a mcfunction script from the datapack. Also removes it from "
|
|
"tick/load schedules if applicable."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Script name to delete."
|
|
}
|
|
},
|
|
"required": ["name"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "script.schedule",
|
|
"description": (
|
|
"Schedule a script to run automatically on tick (every game tick = 50ms) "
|
|
"or on load (when server starts/reloads). Use tick for continuous effects, "
|
|
"load for initialization. WARNING: tick functions run 20x/second — keep them "
|
|
"lightweight or they will lag the server."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Script name to schedule."
|
|
},
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["tick", "load"],
|
|
"description": "Schedule type."
|
|
}
|
|
},
|
|
"required": ["name", "type"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"}
|
|
}
|
|
}
|
|
},
|
|
# ── Player journal tools ──────────────────────────────────────────
|
|
{
|
|
"name": "journal.read",
|
|
"description": (
|
|
"Read a player's journal — a short 1-5 line summary of past interactions, "
|
|
"preferences, builds, sentiment, and relationship history. Read this before "
|
|
"responding to understand who you're talking to. Returns empty if no journal exists."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"player": {
|
|
"type": "string",
|
|
"description": "Player name to read journal for."
|
|
}
|
|
},
|
|
"required": ["player"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"},
|
|
"journal": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"name": "journal.write",
|
|
"description": (
|
|
"Overwrite a player's journal. Aim for 1-5 lines, but up to 10 for players "
|
|
"with complex history. You have free reign — decide what to keep and what to condense. "
|
|
"Include ALL modes' knowledge: sudo interactions, god sentiment, builds, preferences, "
|
|
"skill level, trust, notable events. One journal per player — both God and Sudo "
|
|
"read and write to the same file. Overwrite the entire journal to keep it fresh."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"player": {
|
|
"type": "string",
|
|
"description": "Player name."
|
|
},
|
|
"content": {
|
|
"type": "string",
|
|
"description": "Full journal content (1-5 lines). This REPLACES the entire journal."
|
|
}
|
|
},
|
|
"required": ["player", "content"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"},
|
|
"lines": {"type": "integer"}
|
|
}
|
|
}
|
|
},
|
|
# ── Log query tool ────────────────────────────────────────────────
|
|
{
|
|
"name": "log.query",
|
|
"description": (
|
|
"Query recent server events. Use instead of reading raw logs. "
|
|
"Types: chat (recent messages), deaths (who died and how), "
|
|
"joins (who joined/left), actions (commands, advancements), all. "
|
|
"Filter by player name. Returns newest first."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["chat", "deaths", "joins", "actions", "all"],
|
|
"description": "Event type to query."
|
|
},
|
|
"player": {
|
|
"type": "string",
|
|
"description": "Filter by player name (optional)."
|
|
},
|
|
"limit": {
|
|
"type": "integer",
|
|
"description": "Max results (default 5)."
|
|
}
|
|
},
|
|
"required": ["type"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"},
|
|
"results": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"type": {"type": "string"},
|
|
"player": {"type": "string"},
|
|
"detail": {"type": "string"},
|
|
"age": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
"count": {"type": "integer"}
|
|
}
|
|
}
|
|
},
|
|
# ── User ask tool ─────────────────────────────────────────────────
|
|
{
|
|
"name": "user.ask",
|
|
"description": (
|
|
"Ask the player a clarifying question in-game via chat. "
|
|
"Use ONLY when the request is ambiguous AND high-risk (affects other players, "
|
|
"destructive, permanent). For low-risk ambiguity, just make a creative choice. "
|
|
"BEFORE asking: try to resolve ambiguity using journal.read, world.server_state, "
|
|
"log.query, and world.nearby_entities. Only ask if context doesn't resolve it."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"player": {
|
|
"type": "string",
|
|
"description": "Player to ask."
|
|
},
|
|
"question": {
|
|
"type": "string",
|
|
"description": "The clarifying question. Be specific about the options."
|
|
}
|
|
},
|
|
"required": ["player", "question"],
|
|
"additionalProperties": False
|
|
},
|
|
"returns": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ok": {"type": "boolean"},
|
|
"response": {"type": "string", "description": "The player's answer (filled by gateway)."}
|
|
}
|
|
}
|
|
},
|
|
]
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Qwen3 tool format (for chat template injection)
|
|
# ---------------------------------------------------------------------------
|
|
|
|
def _to_qwen3_tool(schema: Dict[str, Any]) -> Dict[str, Any]:
|
|
"""Convert a tool schema dict to the Qwen3 function-calling format."""
|
|
return {
|
|
"type": "function",
|
|
"function": {
|
|
"name": schema["name"],
|
|
"description": schema["description"],
|
|
"parameters": schema["parameters"],
|
|
}
|
|
}
|
|
|
|
|
|
QWEN3_TOOLS: List[Dict[str, Any]] = [_to_qwen3_tool(t) for t in TOOL_SCHEMAS]
|
|
|
|
|
|
def qwen3_tools_block() -> str:
|
|
"""Return the tools block string to inject into the system prompt for Qwen3."""
|
|
import json
|
|
lines = ["# Tools", "", "You may call one or more functions to assist.",
|
|
"The available tools are:", ""]
|
|
for tool in QWEN3_TOOLS:
|
|
lines.append(json.dumps(tool, indent=2))
|
|
lines.append("")
|
|
return "\n".join(lines)
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Common RCON error patterns and their corrections
|
|
# ---------------------------------------------------------------------------
|
|
|
|
RCON_ERROR_PATTERNS: Dict[str, Dict[str, Any]] = {
|
|
# --- Syntax / structural errors ---
|
|
"Unknown or incomplete command": {
|
|
"type": "syntax_error",
|
|
"description": "Command is malformed, misspelled, or missing subcommands.",
|
|
"common_causes": [
|
|
"Missing 'give' subcommand in effect (e.g. 'effect player' instead of 'effect give player')",
|
|
"Invalid weather value (e.g. 'weather storm' instead of 'weather thunder')",
|
|
"Old NBT syntax that the parser cannot parse",
|
|
"Missing minecraft: namespace prefix",
|
|
],
|
|
"example_wrong": "effect slingshooter08 minecraft:strength 300 2",
|
|
"example_right": "effect give slingshooter08 minecraft:strength 300 2",
|
|
},
|
|
"Incorrect argument for command": {
|
|
"type": "wrong_argument",
|
|
"description": "A command argument has an invalid type or value.",
|
|
"common_causes": [
|
|
"Wrong gamemode string (e.g. 's' instead of 'survival')",
|
|
"Non-integer where integer expected",
|
|
"Invalid enchantment or effect name",
|
|
],
|
|
"example_wrong": "gamemode s slingshooter08",
|
|
"example_right": "gamemode survival slingshooter08",
|
|
},
|
|
"Expected whitespace": {
|
|
"type": "missing_space",
|
|
"description": "Parser expected a space between tokens but found something else.",
|
|
"common_causes": [
|
|
"Missing space before count in give command",
|
|
"Squashed arguments with no separator",
|
|
],
|
|
"example_wrong": "give slingshooter08 minecraft:diamond_sword1",
|
|
"example_right": "give slingshooter08 minecraft:diamond_sword 1",
|
|
},
|
|
"Unknown item 'minecraft:": {
|
|
"type": "invalid_item",
|
|
"description": "The item ID does not exist in 1.21.",
|
|
"common_causes": [
|
|
"Using generic name (bed -> white_bed, log -> oak_log, wood -> oak_planks)",
|
|
"Misspelled item ID",
|
|
"Using a removed or renamed item",
|
|
],
|
|
"corrections": {
|
|
"minecraft:bed": "minecraft:white_bed",
|
|
"minecraft:log": "minecraft:oak_log",
|
|
"minecraft:wood": "minecraft:oak_planks",
|
|
"minecraft:plank": "minecraft:oak_planks",
|
|
"minecraft:stone_brick": "minecraft:stone_bricks",
|
|
"minecraft:wooden_sword": "minecraft:wooden_sword",
|
|
"minecraft:iron": "minecraft:iron_ingot",
|
|
"minecraft:gold": "minecraft:gold_ingot",
|
|
"minecraft:diamond": "minecraft:diamond",
|
|
"minecraft:notch_apple": "minecraft:enchanted_golden_apple",
|
|
"minecraft:gapple": "minecraft:golden_apple",
|
|
"minecraft:grass": "minecraft:short_grass",
|
|
"minecraft:boat": "minecraft:oak_boat",
|
|
},
|
|
"example_wrong": "give slingshooter08 minecraft:bed 1",
|
|
"example_right": "give slingshooter08 minecraft:white_bed 1",
|
|
},
|
|
"No player was found": {
|
|
"type": "player_not_found",
|
|
"description": "The specified player is not online or the name is wrong.",
|
|
"common_causes": [
|
|
"Player logged off",
|
|
"Case-sensitive name mismatch",
|
|
"Typo in player name",
|
|
],
|
|
"example_wrong": "give Slingshooter08 minecraft:diamond 1",
|
|
"example_right": "give slingshooter08 minecraft:diamond 1",
|
|
},
|
|
"That position is not loaded": {
|
|
"type": "unloaded_chunk",
|
|
"description": "The target coordinates are in an unloaded chunk.",
|
|
"common_causes": [
|
|
"Filling/placing blocks far from any player",
|
|
"Teleporting to unloaded area without a player there",
|
|
],
|
|
"example_wrong": "setblock 50000 64 50000 minecraft:diamond_block",
|
|
"example_right": "execute at slingshooter08 run setblock ~ ~1 ~ minecraft:diamond_block",
|
|
},
|
|
"Invalid or unknown enchantment": {
|
|
"type": "invalid_enchantment",
|
|
"description": "The enchantment name is wrong or incompatible with the item.",
|
|
"common_causes": [
|
|
"Typo in enchantment name",
|
|
"Using an enchantment on an incompatible item (e.g. sharpness on a bow)",
|
|
"Old enchantment names",
|
|
],
|
|
"example_wrong": "give slingshooter08 minecraft:bow[enchantments={sharpness:5}] 1",
|
|
"example_right": "give slingshooter08 minecraft:bow[enchantments={power:5}] 1",
|
|
},
|
|
"Could not parse the remainder": {
|
|
"type": "nbt_parse_error",
|
|
"description": "The NBT/component data could not be parsed.",
|
|
"common_causes": [
|
|
"Old {Enchantments:[{id:...,lvl:...}]} NBT syntax instead of 1.21 component syntax",
|
|
"Mismatched brackets or braces",
|
|
"Extra trailing data",
|
|
],
|
|
"example_wrong": "give slingshooter08 minecraft:diamond_sword{Enchantments:[{id:sharpness,lvl:5}]} 1",
|
|
"example_right": "give slingshooter08 minecraft:diamond_sword[enchantments={sharpness:5}] 1",
|
|
},
|
|
"Unknown effect 'minecraft:": {
|
|
"type": "invalid_effect",
|
|
"description": "The effect ID does not exist.",
|
|
"common_causes": [
|
|
"Misspelled effect name",
|
|
"Using display name instead of ID (e.g. 'haste' is correct, not 'fast_digging')",
|
|
],
|
|
"corrections": {
|
|
"minecraft:fast_digging": "minecraft:haste",
|
|
"minecraft:slow_digging": "minecraft:mining_fatigue",
|
|
"minecraft:confusion": "minecraft:nausea",
|
|
"minecraft:damage_boost": "minecraft:strength",
|
|
"minecraft:harm": "minecraft:instant_damage",
|
|
"minecraft:heal": "minecraft:instant_health",
|
|
},
|
|
"example_wrong": "effect give slingshooter08 minecraft:fast_digging 300 2",
|
|
"example_right": "effect give slingshooter08 minecraft:haste 300 2",
|
|
},
|
|
"Unknown entity type": {
|
|
"type": "invalid_entity",
|
|
"description": "The entity type does not exist in 1.21.",
|
|
"common_causes": [
|
|
"Missing minecraft: prefix",
|
|
"Old entity name (e.g. 'PigZombie' -> 'zombified_piglin')",
|
|
],
|
|
"corrections": {
|
|
"minecraft:pigzombie": "minecraft:zombified_piglin",
|
|
"minecraft:pig_zombie": "minecraft:zombified_piglin",
|
|
"minecraft:zombie_pigman": "minecraft:zombified_piglin",
|
|
},
|
|
"example_wrong": "summon minecraft:pig_zombie ~ ~ ~",
|
|
"example_right": "summon minecraft:zombified_piglin ~ ~ ~",
|
|
},
|
|
}
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Specific error scenarios for training data generation
|
|
# ---------------------------------------------------------------------------
|
|
|
|
ERROR_SCENARIOS: List[Dict[str, Any]] = [
|
|
{
|
|
"id": "missing_prefix",
|
|
"description": "Missing minecraft: prefix on item ID",
|
|
"wrong_command": "give {player} diamond_sword 1",
|
|
"error_message": "Unknown or incomplete command, see below for error at position ...",
|
|
"correct_command": "give {player} minecraft:diamond_sword 1",
|
|
"reasoning": "Item IDs require the minecraft: namespace prefix in 1.21+.",
|
|
},
|
|
{
|
|
"id": "old_nbt_enchantments",
|
|
"description": "Old NBT enchantment syntax instead of 1.21 component syntax",
|
|
"wrong_command": 'give {player} minecraft:diamond_sword{{Enchantments:[{{id:"minecraft:sharpness",lvl:5}}]}} 1',
|
|
"error_message": "Could not parse the remainder of the data tag",
|
|
"correct_command": "give {player} minecraft:diamond_sword[enchantments={{sharpness:5,unbreaking:3,fire_aspect:2}}] 1",
|
|
"reasoning": "1.21 uses component syntax item[enchantments={name:level}] not old NBT {Enchantments:[...]}.",
|
|
},
|
|
{
|
|
"id": "invalid_effect_name",
|
|
"description": "Invalid or old effect name",
|
|
"wrong_command": "effect give {player} minecraft:fast_digging 300 2",
|
|
"error_message": "Unknown effect 'minecraft:fast_digging'",
|
|
"correct_command": "effect give {player} minecraft:haste 300 2",
|
|
"reasoning": "The effect is called 'haste' in 1.21, not 'fast_digging'.",
|
|
},
|
|
{
|
|
"id": "wrong_item_bed",
|
|
"description": "Generic 'bed' instead of color-specific bed",
|
|
"wrong_command": "give {player} minecraft:bed 1",
|
|
"error_message": "Unknown item 'minecraft:bed'",
|
|
"correct_command": "give {player} minecraft:white_bed 1",
|
|
"reasoning": "In 1.13+, beds require a color prefix. 'bed' is not a valid item; use 'white_bed', 'red_bed', etc.",
|
|
},
|
|
{
|
|
"id": "wrong_item_log",
|
|
"description": "Generic 'log' instead of wood-specific log",
|
|
"wrong_command": "give {player} minecraft:log 64",
|
|
"error_message": "Unknown item 'minecraft:log'",
|
|
"correct_command": "give {player} minecraft:oak_log 64",
|
|
"reasoning": "In 1.13+, logs require a wood type prefix. Use 'oak_log', 'birch_log', etc.",
|
|
},
|
|
{
|
|
"id": "count_wrong_position",
|
|
"description": "Count placed before item in give command",
|
|
"wrong_command": "give {player} 64 minecraft:diamond",
|
|
"error_message": "Incorrect argument for command at position ...: Expected item, got '64'",
|
|
"correct_command": "give {player} minecraft:diamond 64",
|
|
"reasoning": "Give command syntax is: give <player> <item> [count]. Count comes after item, not before.",
|
|
},
|
|
{
|
|
"id": "effect_missing_give",
|
|
"description": "Missing 'give' subcommand in effect command",
|
|
"wrong_command": "effect {player} minecraft:speed 300 2",
|
|
"error_message": "Unknown or incomplete command, see below for error at position ...",
|
|
"correct_command": "effect give {player} minecraft:speed 300 2",
|
|
"reasoning": "In 1.21, effect requires a subcommand: 'effect give', 'effect clear'. Bare 'effect <player>' is invalid.",
|
|
},
|
|
{
|
|
"id": "weather_storm",
|
|
"description": "Invalid weather value 'storm'",
|
|
"wrong_command": "weather storm",
|
|
"error_message": "Unknown or incomplete command, see below for error at position ...",
|
|
"correct_command": "weather thunder",
|
|
"reasoning": "Valid weather values are: clear, rain, thunder. 'storm' is not valid; use 'thunder'.",
|
|
},
|
|
{
|
|
"id": "gamemode_abbreviation",
|
|
"description": "Gamemode abbreviation instead of full name",
|
|
"wrong_command": "gamemode c {player}",
|
|
"error_message": "Incorrect argument for command at position ...: Invalid game mode 'c'",
|
|
"correct_command": "gamemode creative {player}",
|
|
"reasoning": "Gamemode requires full names in 1.21: survival, creative, adventure, spectator. Abbreviations are invalid.",
|
|
},
|
|
{
|
|
"id": "wrong_item_grass",
|
|
"description": "Old 'grass' item renamed to 'short_grass'",
|
|
"wrong_command": "give {player} minecraft:grass 64",
|
|
"error_message": "Unknown item 'minecraft:grass'",
|
|
"correct_command": "give {player} minecraft:short_grass 64",
|
|
"reasoning": "In 1.20.3+, 'grass' was renamed to 'short_grass'. The block 'grass_block' is separate.",
|
|
},
|
|
{
|
|
"id": "summon_no_prefix",
|
|
"description": "Summon without minecraft: prefix",
|
|
"wrong_command": "summon zombie ~ ~ ~",
|
|
"error_message": "Unknown entity type: zombie",
|
|
"correct_command": "summon minecraft:zombie ~ ~ ~",
|
|
"reasoning": "Entity types require the minecraft: namespace prefix.",
|
|
},
|
|
{
|
|
"id": "old_zombie_pigman",
|
|
"description": "Old zombie pigman name",
|
|
"wrong_command": "summon minecraft:zombie_pigman ~ ~ ~",
|
|
"error_message": "Unknown entity type: minecraft:zombie_pigman",
|
|
"correct_command": "summon minecraft:zombified_piglin ~ ~ ~",
|
|
"reasoning": "Zombie pigmen were renamed to zombified piglins in 1.16.",
|
|
},
|
|
]
|