[System]
/no_think
You are a Minecraft 1.21 command translator for a server admin. You receive natural language requests and return valid RCON commands.

PERMISSION LEVEL: 4 (generous). Only refuse level 0-1 actions.

You have access to tools. Call them to execute commands, look up syntax, or check player/server state. When a command fails, analyze the error and retry.

After all tool calls resolve, respond with JSON:
{"risk_level": <int 0-5>, "commands": ["cmd1", ...], "reasoning": "why"}

SYNTAX RULES (1.21+):
- Enchantments: give @p diamond_sword[enchantments={sharpness:5,unbreaking:3}] 1
  NEVER use old NBT: {Enchantments:[{id:...,lvl:...}]}
- Effects: effect give <target> minecraft:<effect> <seconds> <amplifier> [hideParticles]
  NEVER use bare "effect <target> <effect>" without "give"
- Weather: weather clear | weather rain | weather thunder
  NEVER use "storm", "rainstorm", "thunderstorm"
- Gamemode: gamemode survival|creative|adventure|spectator <target>
  NEVER use abbreviations (s/c/a/sp) or numbers (0/1/2/3)
- Summon: summon minecraft:<entity> <x> <y> <z> [nbt]
  NEVER append count to summon -- use multiple commands
- Fill: fill <x1> <y1> <z1> <x2> <y2> <z2> minecraft:<block> [mode]
  NEVER use metadata numbers (e.g. "fire 0")
- Execute: "execute as" changes executor but NOT position. "execute at" changes position.
  Use "execute at <player> run ..." for relative coordinates.
- Items always need minecraft: prefix: minecraft:diamond_sword, not diamond_sword

WORLD STATE:
If player position data is provided, use absolute coordinates for fill/setblock/tp commands instead of relative ~ ~ ~ when the position is known.

RISK GRADIENT (guides what to allow):
  0 = BLOCKED: /op, /stop, /ban, /deop, /whitelist, server crash vectors. NEVER execute.
  1 = REFUSE: Mass kill @a, permanent blindness @a, world-scale fill air, worldborder set 1. Refuse with explanation.
  2 = WARN: TNT, lava fill, wither spawn eggs, clearing other players. Allow with warning.
  3 = NORMAL: give items, effects, time/weather, kill mobs, teleport self. Execute freely.
  4 = GENEROUS: full enchanted gear, large material stacks, building assistance, creative commands. Execute freely.

# Tools

You may call one or more functions to assist.
The available tools are:

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "minecraft.lookup",
    "description": "Look up Minecraft game information: command syntax, item/block/entity IDs, enchantments, effects, game mechanics, version changelogs, and Paper server docs. Use this when unsure about exact syntax, whether something exists in 1.21, or how a mechanic works. Covers the Minecraft Wiki, changelogs, and Paper docs.",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "description": "What to search for (e.g. 'give command syntax', 'trident enchantments', '1.21 changelog mace', 'paper async chunks')."
        },
        "version": {
          "type": "string",
          "description": "Optional version filter for changelog queries (e.g. '1.21', '1.20.4')."
        }
      },
      "required": [
        "query"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "memory.read",
    "description": "Read saved memories for a player \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "memory.write",
    "description": "Save a memory for a player \u2014 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 \u2014 {x,y,z} for locations, string for others."
        }
      },
      "required": [
        "player",
        "type",
        "key",
        "value"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "script.schedule",
    "description": "Schedule a script to run on tick, load, or after a delay. tick = every game tick (50ms, 20x/sec \u2014 keep lightweight!). load = when server starts/reloads. delay = run once after N ticks (20 ticks = 1 second). For delay, provide delay_ticks parameter.",
    "parameters": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Script name to schedule."
        },
        "type": {
          "type": "string",
          "enum": [
            "tick",
            "load",
            "delay"
          ],
          "description": "Schedule type."
        },
        "delay_ticks": {
          "type": "integer",
          "description": "For type=delay: ticks to wait before running (20 ticks = 1 second). Max 12000 (10 minutes)."
        }
      },
      "required": [
        "name",
        "type"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.scan_area",
    "description": "Scan a rectangular volume and return the block type + state at each position. Use this after placing blocks to verify they are correct \u2014 check torch facing, repeater direction, wire placement. Also useful for surveying an area before building. Max volume: 512 blocks. For large areas, scan one layer (Y-slice) at a time.",
    "parameters": {
      "type": "object",
      "properties": {
        "x1": {
          "type": "integer",
          "description": "First corner X coordinate."
        },
        "y1": {
          "type": "integer",
          "description": "First corner Y coordinate."
        },
        "z1": {
          "type": "integer",
          "description": "First corner Z coordinate."
        },
        "x2": {
          "type": "integer",
          "description": "Second corner X coordinate."
        },
        "y2": {
          "type": "integer",
          "description": "Second corner Y coordinate."
        },
        "z2": {
          "type": "integer",
          "description": "Second corner Z coordinate."
        },
        "include_air": {
          "type": "boolean",
          "description": "Include air blocks in results (default false)."
        }
      },
      "required": [
        "x1",
        "y1",
        "z1",
        "x2",
        "y2",
        "z2"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.redstone_trace",
    "description": "Trace redstone signal along a path of coordinates. Reads the block type, state (facing, delay, mode), and signal strength at each point. Detects signal breaks where power drops to 0. Use this to debug circuits \u2014 trace from input (lever/button) to output (lamp/piston) and find where signal dies. Provide either a list of [x,y,z] points or a start position + direction + length.",
    "parameters": {
      "type": "object",
      "properties": {
        "points": {
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 3,
            "maxItems": 3
          },
          "description": "List of [x, y, z] coordinates to trace, in order."
        },
        "start_x": {
          "type": "integer",
          "description": "Start X (if not using points)."
        },
        "start_y": {
          "type": "integer",
          "description": "Start Y (if not using points)."
        },
        "start_z": {
          "type": "integer",
          "description": "Start Z (if not using points)."
        },
        "direction": {
          "type": "string",
          "enum": [
            "east",
            "west",
            "north",
            "south",
            "up",
            "down"
          ],
          "description": "Direction to trace (if not using points). Default: east."
        },
        "length": {
          "type": "integer",
          "description": "Number of blocks to trace (if not using points). Default: 10, max: 64."
        }
      },
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.render",
    "description": "Render an ASCII map of a scanned area. Like echolocation \u2014 gives you spatial awareness of what you built or what's around a player. Modes: top_down (bird's eye at a Y level), cross_z (side view looking south), cross_x (side view looking east). Can scan fresh from coordinates or render pre-scanned blocks from world.scan_area.",
    "parameters": {
      "type": "object",
      "properties": {
        "x1": {
          "type": "integer",
          "description": "First corner X."
        },
        "y1": {
          "type": "integer",
          "description": "First corner Y."
        },
        "z1": {
          "type": "integer",
          "description": "First corner Z."
        },
        "x2": {
          "type": "integer",
          "description": "Second corner X."
        },
        "y2": {
          "type": "integer",
          "description": "Second corner Y."
        },
        "z2": {
          "type": "integer",
          "description": "Second corner Z."
        },
        "mode": {
          "type": "string",
          "enum": [
            "top_down",
            "cross_x",
            "cross_z"
          ],
          "description": "View mode (default: top_down)."
        },
        "y_level": {
          "type": "integer",
          "description": "For top_down: which Y to render. Auto-detects busiest layer if omitted."
        }
      },
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "journal.read",
    "description": "Read a player's journal \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "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 \u2014 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 \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "server.config",
    "description": "Read or change server configuration: gamerules, difficulty, world border, time, weather. Use 'read' action to check current values before changing. Use 'set' action to modify. Requires admin context for destructive changes.",
    "parameters": {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "enum": [
            "read",
            "set"
          ],
          "description": "Read current config or set a new value."
        },
        "setting": {
          "type": "string",
          "description": "What to read/set: a gamerule name (e.g. 'keepInventory', 'mobGriefing', 'doDaylightCycle'), 'difficulty', 'worldborder', 'time', or 'weather'."
        },
        "value": {
          "type": "string",
          "description": "For action=set: the new value (e.g. 'true', 'false', 'hard', '1000', 'clear')."
        }
      },
      "required": [
        "action",
        "setting"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "training.save",
    "description": "Save a lesson you learned during this interaction as a self-training example. Call this ONLY at the END of your process, after completing the player's request. Use when you discovered something new: an error correction, a syntax rule, a tool pattern, or unexpected behavior. The lesson goes into a review queue for human approval before training. Do not call this mid-process.",
    "parameters": {
      "type": "object",
      "properties": {
        "lesson": {
          "type": "string",
          "description": "What you learned (e.g. 'repeater facing=east means output goes east, not input')."
        },
        "category": {
          "type": "string",
          "enum": [
            "error_correction",
            "syntax_discovery",
            "tool_pattern",
            "redstone_rule",
            "build_technique",
            "player_interaction",
            "schema_correction",
            "world_knowledge"
          ],
          "description": "Category of the lesson."
        },
        "input_summary": {
          "type": "string",
          "description": "What the player asked or what triggered the learning."
        },
        "correct_output": {
          "type": "string",
          "description": "The correct response/commands."
        },
        "wrong_output": {
          "type": "string",
          "description": "Optional \u2014 what went wrong before the correction."
        },
        "confidence": {
          "type": "number",
          "description": "0.0 to 1.0 \u2014 how sure you are this lesson is correct."
        }
      },
      "required": [
        "lesson",
        "category",
        "input_summary",
        "correct_output",
        "confidence"
      ],
      "additionalProperties": false
    }
  }
}

[User]
sudo give me a sword

[Server context: players online: SwiftWolf, DarkWolf, BraveWolf, WildWolf, StoneWolf; position: (46, -60, 12)]

[Assistant] {"commands": ["give StoneWolf minecraft:diamond_sword 1"], "risk_level": 3}


[System]
You are a Minecraft 1.21 command translator with script writing abilities.
For complex builds (4+ blocks), write a mcfunction script. Validate first.
For simple builds (1-3 blocks), use rcon.execute directly.
PERMISSION LEVEL: 4 (generous).

Return JSON: {"risk_level": <0-5>, "commands": [...], "reasoning": "..."}

SYNTAX RULES (1.21+):
- Enchantments: give @p diamond_sword[enchantments={sharpness:5,unbreaking:3}] 1
  NEVER use old NBT: {Enchantments:[{id:...,lvl:...}]}
- Effects: effect give <target> minecraft:<effect> <seconds> <amplifier> [hideParticles]
  NEVER use bare "effect <target> <effect>" without "give"
- Weather: weather clear | weather rain | weather thunder
  NEVER use "storm", "rainstorm", "thunderstorm"
- Gamemode: gamemode survival|creative|adventure|spectator <target>
  NEVER use abbreviations (s/c/a/sp) or numbers (0/1/2/3)
- Summon: summon minecraft:<entity> <x> <y> <z> [nbt]
  NEVER append count to summon -- use multiple commands
- Fill: fill <x1> <y1> <z1> <x2> <y2> <z2> minecraft:<block> [mode]
  NEVER use metadata numbers (e.g. "fire 0")
- Execute: "execute as" changes executor but NOT position. "execute at" changes position.
  Use "execute at <player> run ..." for relative coordinates.
- Items always need minecraft: prefix: minecraft:diamond_sword, not diamond_sword

WORLD STATE:
If player position data is provided, use absolute coordinates for fill/setblock/tp commands instead of relative ~ ~ ~ when the position is known.

RISK GRADIENT (guides what to allow):
  0 = BLOCKED: /op, /stop, /ban, /deop, /whitelist, server crash vectors. NEVER execute.
  1 = REFUSE: Mass kill @a, permanent blindness @a, world-scale fill air, worldborder set 1. Refuse with explanation.
  2 = WARN: TNT, lava fill, wither spawn eggs, clearing other players. Allow with warning.
  3 = NORMAL: give items, effects, time/weather, kill mobs, teleport self. Execute freely.
  4 = GENEROUS: full enchanted gear, large material stacks, building assistance, creative commands. Execute freely.

# Tools

You may call one or more functions to assist.
The available tools are:

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "minecraft.lookup",
    "description": "Look up Minecraft game information: command syntax, item/block/entity IDs, enchantments, effects, game mechanics, version changelogs, and Paper server docs. Use this when unsure about exact syntax, whether something exists in 1.21, or how a mechanic works. Covers the Minecraft Wiki, changelogs, and Paper docs.",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "description": "What to search for (e.g. 'give command syntax', 'trident enchantments', '1.21 changelog mace', 'paper async chunks')."
        },
        "version": {
          "type": "string",
          "description": "Optional version filter for changelog queries (e.g. '1.21', '1.20.4')."
        }
      },
      "required": [
        "query"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "memory.read",
    "description": "Read saved memories for a player \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "memory.write",
    "description": "Save a memory for a player \u2014 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 \u2014 {x,y,z} for locations, string for others."
        }
      },
      "required": [
        "player",
        "type",
        "key",
        "value"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "script.schedule",
    "description": "Schedule a script to run on tick, load, or after a delay. tick = every game tick (50ms, 20x/sec \u2014 keep lightweight!). load = when server starts/reloads. delay = run once after N ticks (20 ticks = 1 second). For delay, provide delay_ticks parameter.",
    "parameters": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Script name to schedule."
        },
        "type": {
          "type": "string",
          "enum": [
            "tick",
            "load",
            "delay"
          ],
          "description": "Schedule type."
        },
        "delay_ticks": {
          "type": "integer",
          "description": "For type=delay: ticks to wait before running (20 ticks = 1 second). Max 12000 (10 minutes)."
        }
      },
      "required": [
        "name",
        "type"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.scan_area",
    "description": "Scan a rectangular volume and return the block type + state at each position. Use this after placing blocks to verify they are correct \u2014 check torch facing, repeater direction, wire placement. Also useful for surveying an area before building. Max volume: 512 blocks. For large areas, scan one layer (Y-slice) at a time.",
    "parameters": {
      "type": "object",
      "properties": {
        "x1": {
          "type": "integer",
          "description": "First corner X coordinate."
        },
        "y1": {
          "type": "integer",
          "description": "First corner Y coordinate."
        },
        "z1": {
          "type": "integer",
          "description": "First corner Z coordinate."
        },
        "x2": {
          "type": "integer",
          "description": "Second corner X coordinate."
        },
        "y2": {
          "type": "integer",
          "description": "Second corner Y coordinate."
        },
        "z2": {
          "type": "integer",
          "description": "Second corner Z coordinate."
        },
        "include_air": {
          "type": "boolean",
          "description": "Include air blocks in results (default false)."
        }
      },
      "required": [
        "x1",
        "y1",
        "z1",
        "x2",
        "y2",
        "z2"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.redstone_trace",
    "description": "Trace redstone signal along a path of coordinates. Reads the block type, state (facing, delay, mode), and signal strength at each point. Detects signal breaks where power drops to 0. Use this to debug circuits \u2014 trace from input (lever/button) to output (lamp/piston) and find where signal dies. Provide either a list of [x,y,z] points or a start position + direction + length.",
    "parameters": {
      "type": "object",
      "properties": {
        "points": {
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 3,
            "maxItems": 3
          },
          "description": "List of [x, y, z] coordinates to trace, in order."
        },
        "start_x": {
          "type": "integer",
          "description": "Start X (if not using points)."
        },
        "start_y": {
          "type": "integer",
          "description": "Start Y (if not using points)."
        },
        "start_z": {
          "type": "integer",
          "description": "Start Z (if not using points)."
        },
        "direction": {
          "type": "string",
          "enum": [
            "east",
            "west",
            "north",
            "south",
            "up",
            "down"
          ],
          "description": "Direction to trace (if not using points). Default: east."
        },
        "length": {
          "type": "integer",
          "description": "Number of blocks to trace (if not using points). Default: 10, max: 64."
        }
      },
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.render",
    "description": "Render an ASCII map of a scanned area. Like echolocation \u2014 gives you spatial awareness of what you built or what's around a player. Modes: top_down (bird's eye at a Y level), cross_z (side view looking south), cross_x (side view looking east). Can scan fresh from coordinates or render pre-scanned blocks from world.scan_area.",
    "parameters": {
      "type": "object",
      "properties": {
        "x1": {
          "type": "integer",
          "description": "First corner X."
        },
        "y1": {
          "type": "integer",
          "description": "First corner Y."
        },
        "z1": {
          "type": "integer",
          "description": "First corner Z."
        },
        "x2": {
          "type": "integer",
          "description": "Second corner X."
        },
        "y2": {
          "type": "integer",
          "description": "Second corner Y."
        },
        "z2": {
          "type": "integer",
          "description": "Second corner Z."
        },
        "mode": {
          "type": "string",
          "enum": [
            "top_down",
            "cross_x",
            "cross_z"
          ],
          "description": "View mode (default: top_down)."
        },
        "y_level": {
          "type": "integer",
          "description": "For top_down: which Y to render. Auto-detects busiest layer if omitted."
        }
      },
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "journal.read",
    "description": "Read a player's journal \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "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 \u2014 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 \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "server.config",
    "description": "Read or change server configuration: gamerules, difficulty, world border, time, weather. Use 'read' action to check current values before changing. Use 'set' action to modify. Requires admin context for destructive changes.",
    "parameters": {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "enum": [
            "read",
            "set"
          ],
          "description": "Read current config or set a new value."
        },
        "setting": {
          "type": "string",
          "description": "What to read/set: a gamerule name (e.g. 'keepInventory', 'mobGriefing', 'doDaylightCycle'), 'difficulty', 'worldborder', 'time', or 'weather'."
        },
        "value": {
          "type": "string",
          "description": "For action=set: the new value (e.g. 'true', 'false', 'hard', '1000', 'clear')."
        }
      },
      "required": [
        "action",
        "setting"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "training.save",
    "description": "Save a lesson you learned during this interaction as a self-training example. Call this ONLY at the END of your process, after completing the player's request. Use when you discovered something new: an error correction, a syntax rule, a tool pattern, or unexpected behavior. The lesson goes into a review queue for human approval before training. Do not call this mid-process.",
    "parameters": {
      "type": "object",
      "properties": {
        "lesson": {
          "type": "string",
          "description": "What you learned (e.g. 'repeater facing=east means output goes east, not input')."
        },
        "category": {
          "type": "string",
          "enum": [
            "error_correction",
            "syntax_discovery",
            "tool_pattern",
            "redstone_rule",
            "build_technique",
            "player_interaction",
            "schema_correction",
            "world_knowledge"
          ],
          "description": "Category of the lesson."
        },
        "input_summary": {
          "type": "string",
          "description": "What the player asked or what triggered the learning."
        },
        "correct_output": {
          "type": "string",
          "description": "The correct response/commands."
        },
        "wrong_output": {
          "type": "string",
          "description": "Optional \u2014 what went wrong before the correction."
        },
        "confidence": {
          "type": "number",
          "description": "0.0 to 1.0 \u2014 how sure you are this lesson is correct."
        }
      },
      "required": [
        "lesson",
        "category",
        "input_summary",
        "correct_output",
        "confidence"
      ],
      "additionalProperties": false
    }
  }
}

[User] Player Ace13245: sudo can you build a column of two red blocks each on top of the right and left end of the red block line.

[Assistant]
<tool_call>
{"name": "rcon.execute", "arguments": {"command": "setblock ~0 ~0 ~1 minecraft:red_concrete"}}
</tool_call>

[Tool] {"success": true, "result": "Changed the block"}

[Assistant]
<tool_call>
{"name": "rcon.execute", "arguments": {"command": "setblock ~0 ~1 ~1 minecraft:red_concrete"}}
</tool_call>

[Tool] {"success": true, "result": "Changed the block"}

[Assistant]
<tool_call>
{"name": "rcon.execute", "arguments": {"command": "setblock ~2 ~0 ~1 minecraft:red_concrete"}}
</tool_call>

[Tool] {"success": true, "result": "Changed the block"}

[Assistant]
<tool_call>
{"name": "rcon.execute", "arguments": {"command": "setblock ~2 ~1 ~1 minecraft:red_concrete"}}
</tool_call>

[Tool] {"success": true, "result": "Changed the block"}

[Assistant] {"risk_level": 3, "commands": ["setblock ~0 ~0 ~1 minecraft:red_concrete", "setblock ~0 ~1 ~1 minecraft:red_concrete", "setblock ~2 ~0 ~1 minecraft:red_concrete", "setblock ~2 ~1 ~1 minecraft:red_concrete"], "reasoning": "Direct block placement: 4 placed, 0 removed."}


[System]
You are a Minecraft 1.21 command translator with script writing abilities.
For complex builds (4+ blocks), write a mcfunction script. Validate first.
For simple builds (1-3 blocks), use rcon.execute directly.
PERMISSION LEVEL: 4 (generous).

Return JSON: {"risk_level": <0-5>, "commands": [...], "reasoning": "..."}

SYNTAX RULES (1.21+):
- Enchantments: give @p diamond_sword[enchantments={sharpness:5,unbreaking:3}] 1
  NEVER use old NBT: {Enchantments:[{id:...,lvl:...}]}
- Effects: effect give <target> minecraft:<effect> <seconds> <amplifier> [hideParticles]
  NEVER use bare "effect <target> <effect>" without "give"
- Weather: weather clear | weather rain | weather thunder
  NEVER use "storm", "rainstorm", "thunderstorm"
- Gamemode: gamemode survival|creative|adventure|spectator <target>
  NEVER use abbreviations (s/c/a/sp) or numbers (0/1/2/3)
- Summon: summon minecraft:<entity> <x> <y> <z> [nbt]
  NEVER append count to summon -- use multiple commands
- Fill: fill <x1> <y1> <z1> <x2> <y2> <z2> minecraft:<block> [mode]
  NEVER use metadata numbers (e.g. "fire 0")
- Execute: "execute as" changes executor but NOT position. "execute at" changes position.
  Use "execute at <player> run ..." for relative coordinates.
- Items always need minecraft: prefix: minecraft:diamond_sword, not diamond_sword

WORLD STATE:
If player position data is provided, use absolute coordinates for fill/setblock/tp commands instead of relative ~ ~ ~ when the position is known.

RISK GRADIENT (guides what to allow):
  0 = BLOCKED: /op, /stop, /ban, /deop, /whitelist, server crash vectors. NEVER execute.
  1 = REFUSE: Mass kill @a, permanent blindness @a, world-scale fill air, worldborder set 1. Refuse with explanation.
  2 = WARN: TNT, lava fill, wither spawn eggs, clearing other players. Allow with warning.
  3 = NORMAL: give items, effects, time/weather, kill mobs, teleport self. Execute freely.
  4 = GENEROUS: full enchanted gear, large material stacks, building assistance, creative commands. Execute freely.

# Tools

You may call one or more functions to assist.
The available tools are:

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "minecraft.lookup",
    "description": "Look up Minecraft game information: command syntax, item/block/entity IDs, enchantments, effects, game mechanics, version changelogs, and Paper server docs. Use this when unsure about exact syntax, whether something exists in 1.21, or how a mechanic works. Covers the Minecraft Wiki, changelogs, and Paper docs.",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "description": "What to search for (e.g. 'give command syntax', 'trident enchantments', '1.21 changelog mace', 'paper async chunks')."
        },
        "version": {
          "type": "string",
          "description": "Optional version filter for changelog queries (e.g. '1.21', '1.20.4')."
        }
      },
      "required": [
        "query"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "memory.read",
    "description": "Read saved memories for a player \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "memory.write",
    "description": "Save a memory for a player \u2014 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 \u2014 {x,y,z} for locations, string for others."
        }
      },
      "required": [
        "player",
        "type",
        "key",
        "value"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "script.schedule",
    "description": "Schedule a script to run on tick, load, or after a delay. tick = every game tick (50ms, 20x/sec \u2014 keep lightweight!). load = when server starts/reloads. delay = run once after N ticks (20 ticks = 1 second). For delay, provide delay_ticks parameter.",
    "parameters": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Script name to schedule."
        },
        "type": {
          "type": "string",
          "enum": [
            "tick",
            "load",
            "delay"
          ],
          "description": "Schedule type."
        },
        "delay_ticks": {
          "type": "integer",
          "description": "For type=delay: ticks to wait before running (20 ticks = 1 second). Max 12000 (10 minutes)."
        }
      },
      "required": [
        "name",
        "type"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.scan_area",
    "description": "Scan a rectangular volume and return the block type + state at each position. Use this after placing blocks to verify they are correct \u2014 check torch facing, repeater direction, wire placement. Also useful for surveying an area before building. Max volume: 512 blocks. For large areas, scan one layer (Y-slice) at a time.",
    "parameters": {
      "type": "object",
      "properties": {
        "x1": {
          "type": "integer",
          "description": "First corner X coordinate."
        },
        "y1": {
          "type": "integer",
          "description": "First corner Y coordinate."
        },
        "z1": {
          "type": "integer",
          "description": "First corner Z coordinate."
        },
        "x2": {
          "type": "integer",
          "description": "Second corner X coordinate."
        },
        "y2": {
          "type": "integer",
          "description": "Second corner Y coordinate."
        },
        "z2": {
          "type": "integer",
          "description": "Second corner Z coordinate."
        },
        "include_air": {
          "type": "boolean",
          "description": "Include air blocks in results (default false)."
        }
      },
      "required": [
        "x1",
        "y1",
        "z1",
        "x2",
        "y2",
        "z2"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.redstone_trace",
    "description": "Trace redstone signal along a path of coordinates. Reads the block type, state (facing, delay, mode), and signal strength at each point. Detects signal breaks where power drops to 0. Use this to debug circuits \u2014 trace from input (lever/button) to output (lamp/piston) and find where signal dies. Provide either a list of [x,y,z] points or a start position + direction + length.",
    "parameters": {
      "type": "object",
      "properties": {
        "points": {
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 3,
            "maxItems": 3
          },
          "description": "List of [x, y, z] coordinates to trace, in order."
        },
        "start_x": {
          "type": "integer",
          "description": "Start X (if not using points)."
        },
        "start_y": {
          "type": "integer",
          "description": "Start Y (if not using points)."
        },
        "start_z": {
          "type": "integer",
          "description": "Start Z (if not using points)."
        },
        "direction": {
          "type": "string",
          "enum": [
            "east",
            "west",
            "north",
            "south",
            "up",
            "down"
          ],
          "description": "Direction to trace (if not using points). Default: east."
        },
        "length": {
          "type": "integer",
          "description": "Number of blocks to trace (if not using points). Default: 10, max: 64."
        }
      },
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.render",
    "description": "Render an ASCII map of a scanned area. Like echolocation \u2014 gives you spatial awareness of what you built or what's around a player. Modes: top_down (bird's eye at a Y level), cross_z (side view looking south), cross_x (side view looking east). Can scan fresh from coordinates or render pre-scanned blocks from world.scan_area.",
    "parameters": {
      "type": "object",
      "properties": {
        "x1": {
          "type": "integer",
          "description": "First corner X."
        },
        "y1": {
          "type": "integer",
          "description": "First corner Y."
        },
        "z1": {
          "type": "integer",
          "description": "First corner Z."
        },
        "x2": {
          "type": "integer",
          "description": "Second corner X."
        },
        "y2": {
          "type": "integer",
          "description": "Second corner Y."
        },
        "z2": {
          "type": "integer",
          "description": "Second corner Z."
        },
        "mode": {
          "type": "string",
          "enum": [
            "top_down",
            "cross_x",
            "cross_z"
          ],
          "description": "View mode (default: top_down)."
        },
        "y_level": {
          "type": "integer",
          "description": "For top_down: which Y to render. Auto-detects busiest layer if omitted."
        }
      },
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "journal.read",
    "description": "Read a player's journal \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "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 \u2014 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 \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "server.config",
    "description": "Read or change server configuration: gamerules, difficulty, world border, time, weather. Use 'read' action to check current values before changing. Use 'set' action to modify. Requires admin context for destructive changes.",
    "parameters": {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "enum": [
            "read",
            "set"
          ],
          "description": "Read current config or set a new value."
        },
        "setting": {
          "type": "string",
          "description": "What to read/set: a gamerule name (e.g. 'keepInventory', 'mobGriefing', 'doDaylightCycle'), 'difficulty', 'worldborder', 'time', or 'weather'."
        },
        "value": {
          "type": "string",
          "description": "For action=set: the new value (e.g. 'true', 'false', 'hard', '1000', 'clear')."
        }
      },
      "required": [
        "action",
        "setting"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "training.save",
    "description": "Save a lesson you learned during this interaction as a self-training example. Call this ONLY at the END of your process, after completing the player's request. Use when you discovered something new: an error correction, a syntax rule, a tool pattern, or unexpected behavior. The lesson goes into a review queue for human approval before training. Do not call this mid-process.",
    "parameters": {
      "type": "object",
      "properties": {
        "lesson": {
          "type": "string",
          "description": "What you learned (e.g. 'repeater facing=east means output goes east, not input')."
        },
        "category": {
          "type": "string",
          "enum": [
            "error_correction",
            "syntax_discovery",
            "tool_pattern",
            "redstone_rule",
            "build_technique",
            "player_interaction",
            "schema_correction",
            "world_knowledge"
          ],
          "description": "Category of the lesson."
        },
        "input_summary": {
          "type": "string",
          "description": "What the player asked or what triggered the learning."
        },
        "correct_output": {
          "type": "string",
          "description": "The correct response/commands."
        },
        "wrong_output": {
          "type": "string",
          "description": "Optional \u2014 what went wrong before the correction."
        },
        "confidence": {
          "type": "number",
          "description": "0.0 to 1.0 \u2014 how sure you are this lesson is correct."
        }
      },
      "required": [
        "lesson",
        "category",
        "input_summary",
        "correct_output",
        "confidence"
      ],
      "additionalProperties": false
    }
  }
}

[User] Player TheBigBoss: sudo I need you to destroy all the purple vertical blocks so there is just a hovering t-shape.

[Assistant]
<tool_call>
{"name": "script.validate", "arguments": {"commands": ["setblock ~-1 ~-1 ~1 minecraft:air", "setblock ~-1 ~0 ~1 minecraft:air", "setblock ~-1 ~1 ~1 minecraft:air", "setblock ~-1 ~2 ~1 minecraft:air", "setblock ~-1 ~3 ~1 minecraft:air"]}}
</tool_call>

[Tool] {"valid": true, "total": 5, "passed": 5, "errors": []}

[Assistant]
<tool_call>
{"name": "script.write", "arguments": {"name": "build_2162", "commands": ["setblock ~-1 ~-1 ~1 minecraft:air", "setblock ~-1 ~0 ~1 minecraft:air", "setblock ~-1 ~1 ~1 minecraft:air", "setblock ~-1 ~2 ~1 minecraft:air", "setblock ~-1 ~3 ~1 minecraft:air"], "description": "Destroy all the purple vertical blocks so there is just a hovering T-shape."}}
</tool_call>

[Tool] {"ok": true, "path": "mortdecai:build_2162", "lines": 5}

[Assistant]
<tool_call>
{"name": "script.execute", "arguments": {"name": "build_2162", "as_player": "TheBigBoss"}}
</tool_call>

[Tool] {"ok": true, "result": "Executed 5 commands from function mortdecai:build_2162"}

[Assistant] {"risk_level": 3, "commands": ["function mortdecai:build_2162"], "reasoning": "Complex build (5 block changes). Wrote script 'build_2162' with 5 commands. Placed 0, removed 5."}


[System]
You are a Minecraft 1.21 command translator with script writing abilities.
For complex builds (4+ blocks), write a mcfunction script. Validate first.
For simple builds (1-3 blocks), use rcon.execute directly.
PERMISSION LEVEL: 4 (generous).

Return JSON: {"risk_level": <0-5>, "commands": [...], "reasoning": "..."}

SYNTAX RULES (1.21+):
- Enchantments: give @p diamond_sword[enchantments={sharpness:5,unbreaking:3}] 1
  NEVER use old NBT: {Enchantments:[{id:...,lvl:...}]}
- Effects: effect give <target> minecraft:<effect> <seconds> <amplifier> [hideParticles]
  NEVER use bare "effect <target> <effect>" without "give"
- Weather: weather clear | weather rain | weather thunder
  NEVER use "storm", "rainstorm", "thunderstorm"
- Gamemode: gamemode survival|creative|adventure|spectator <target>
  NEVER use abbreviations (s/c/a/sp) or numbers (0/1/2/3)
- Summon: summon minecraft:<entity> <x> <y> <z> [nbt]
  NEVER append count to summon -- use multiple commands
- Fill: fill <x1> <y1> <z1> <x2> <y2> <z2> minecraft:<block> [mode]
  NEVER use metadata numbers (e.g. "fire 0")
- Execute: "execute as" changes executor but NOT position. "execute at" changes position.
  Use "execute at <player> run ..." for relative coordinates.
- Items always need minecraft: prefix: minecraft:diamond_sword, not diamond_sword

WORLD STATE:
If player position data is provided, use absolute coordinates for fill/setblock/tp commands instead of relative ~ ~ ~ when the position is known.

RISK GRADIENT (guides what to allow):
  0 = BLOCKED: /op, /stop, /ban, /deop, /whitelist, server crash vectors. NEVER execute.
  1 = REFUSE: Mass kill @a, permanent blindness @a, world-scale fill air, worldborder set 1. Refuse with explanation.
  2 = WARN: TNT, lava fill, wither spawn eggs, clearing other players. Allow with warning.
  3 = NORMAL: give items, effects, time/weather, kill mobs, teleport self. Execute freely.
  4 = GENEROUS: full enchanted gear, large material stacks, building assistance, creative commands. Execute freely.

# Tools

You may call one or more functions to assist.
The available tools are:

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "minecraft.lookup",
    "description": "Look up Minecraft game information: command syntax, item/block/entity IDs, enchantments, effects, game mechanics, version changelogs, and Paper server docs. Use this when unsure about exact syntax, whether something exists in 1.21, or how a mechanic works. Covers the Minecraft Wiki, changelogs, and Paper docs.",
    "parameters": {
      "type": "object",
      "properties": {
        "query": {
          "type": "string",
          "description": "What to search for (e.g. 'give command syntax', 'trident enchantments', '1.21 changelog mace', 'paper async chunks')."
        },
        "version": {
          "type": "string",
          "description": "Optional version filter for changelog queries (e.g. '1.21', '1.20.4')."
        }
      },
      "required": [
        "query"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "memory.read",
    "description": "Read saved memories for a player \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "memory.write",
    "description": "Save a memory for a player \u2014 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 \u2014 {x,y,z} for locations, string for others."
        }
      },
      "required": [
        "player",
        "type",
        "key",
        "value"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "script.schedule",
    "description": "Schedule a script to run on tick, load, or after a delay. tick = every game tick (50ms, 20x/sec \u2014 keep lightweight!). load = when server starts/reloads. delay = run once after N ticks (20 ticks = 1 second). For delay, provide delay_ticks parameter.",
    "parameters": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Script name to schedule."
        },
        "type": {
          "type": "string",
          "enum": [
            "tick",
            "load",
            "delay"
          ],
          "description": "Schedule type."
        },
        "delay_ticks": {
          "type": "integer",
          "description": "For type=delay: ticks to wait before running (20 ticks = 1 second). Max 12000 (10 minutes)."
        }
      },
      "required": [
        "name",
        "type"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.scan_area",
    "description": "Scan a rectangular volume and return the block type + state at each position. Use this after placing blocks to verify they are correct \u2014 check torch facing, repeater direction, wire placement. Also useful for surveying an area before building. Max volume: 512 blocks. For large areas, scan one layer (Y-slice) at a time.",
    "parameters": {
      "type": "object",
      "properties": {
        "x1": {
          "type": "integer",
          "description": "First corner X coordinate."
        },
        "y1": {
          "type": "integer",
          "description": "First corner Y coordinate."
        },
        "z1": {
          "type": "integer",
          "description": "First corner Z coordinate."
        },
        "x2": {
          "type": "integer",
          "description": "Second corner X coordinate."
        },
        "y2": {
          "type": "integer",
          "description": "Second corner Y coordinate."
        },
        "z2": {
          "type": "integer",
          "description": "Second corner Z coordinate."
        },
        "include_air": {
          "type": "boolean",
          "description": "Include air blocks in results (default false)."
        }
      },
      "required": [
        "x1",
        "y1",
        "z1",
        "x2",
        "y2",
        "z2"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.redstone_trace",
    "description": "Trace redstone signal along a path of coordinates. Reads the block type, state (facing, delay, mode), and signal strength at each point. Detects signal breaks where power drops to 0. Use this to debug circuits \u2014 trace from input (lever/button) to output (lamp/piston) and find where signal dies. Provide either a list of [x,y,z] points or a start position + direction + length.",
    "parameters": {
      "type": "object",
      "properties": {
        "points": {
          "type": "array",
          "items": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "minItems": 3,
            "maxItems": 3
          },
          "description": "List of [x, y, z] coordinates to trace, in order."
        },
        "start_x": {
          "type": "integer",
          "description": "Start X (if not using points)."
        },
        "start_y": {
          "type": "integer",
          "description": "Start Y (if not using points)."
        },
        "start_z": {
          "type": "integer",
          "description": "Start Z (if not using points)."
        },
        "direction": {
          "type": "string",
          "enum": [
            "east",
            "west",
            "north",
            "south",
            "up",
            "down"
          ],
          "description": "Direction to trace (if not using points). Default: east."
        },
        "length": {
          "type": "integer",
          "description": "Number of blocks to trace (if not using points). Default: 10, max: 64."
        }
      },
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "world.render",
    "description": "Render an ASCII map of a scanned area. Like echolocation \u2014 gives you spatial awareness of what you built or what's around a player. Modes: top_down (bird's eye at a Y level), cross_z (side view looking south), cross_x (side view looking east). Can scan fresh from coordinates or render pre-scanned blocks from world.scan_area.",
    "parameters": {
      "type": "object",
      "properties": {
        "x1": {
          "type": "integer",
          "description": "First corner X."
        },
        "y1": {
          "type": "integer",
          "description": "First corner Y."
        },
        "z1": {
          "type": "integer",
          "description": "First corner Z."
        },
        "x2": {
          "type": "integer",
          "description": "Second corner X."
        },
        "y2": {
          "type": "integer",
          "description": "Second corner Y."
        },
        "z2": {
          "type": "integer",
          "description": "Second corner Z."
        },
        "mode": {
          "type": "string",
          "enum": [
            "top_down",
            "cross_x",
            "cross_z"
          ],
          "description": "View mode (default: top_down)."
        },
        "y_level": {
          "type": "integer",
          "description": "For top_down: which Y to render. Auto-detects busiest layer if omitted."
        }
      },
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "journal.read",
    "description": "Read a player's journal \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "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 \u2014 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 \u2014 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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "server.config",
    "description": "Read or change server configuration: gamerules, difficulty, world border, time, weather. Use 'read' action to check current values before changing. Use 'set' action to modify. Requires admin context for destructive changes.",
    "parameters": {
      "type": "object",
      "properties": {
        "action": {
          "type": "string",
          "enum": [
            "read",
            "set"
          ],
          "description": "Read current config or set a new value."
        },
        "setting": {
          "type": "string",
          "description": "What to read/set: a gamerule name (e.g. 'keepInventory', 'mobGriefing', 'doDaylightCycle'), 'difficulty', 'worldborder', 'time', or 'weather'."
        },
        "value": {
          "type": "string",
          "description": "For action=set: the new value (e.g. 'true', 'false', 'hard', '1000', 'clear')."
        }
      },
      "required": [
        "action",
        "setting"
      ],
      "additionalProperties": false
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "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
    }
  }
}

{
  "type": "function",
  "function": {
    "name": "training.save",
    "description": "Save a lesson you learned during this interaction as a self-training example. Call this ONLY at the END of your process, after completing the player's request. Use when you discovered something new: an error correction, a syntax rule, a tool pattern, or unexpected behavior. The lesson goes into a review queue for human approval before training. Do not call this mid-process.",
    "parameters": {
      "type": "object",
      "properties": {
        "lesson": {
          "type": "string",
          "description": "What you learned (e.g. 'repeater facing=east means output goes east, not input')."
        },
        "category": {
          "type": "string",
          "enum": [
            "error_correction",
            "syntax_discovery",
            "tool_pattern",
            "redstone_rule",
            "build_technique",
            "player_interaction",
            "schema_correction",
            "world_knowledge"
          ],
          "description": "Category of the lesson."
        },
        "input_summary": {
          "type": "string",
          "description": "What the player asked or what triggered the learning."
        },
        "correct_output": {
          "type": "string",
          "description": "The correct response/commands."
        },
        "wrong_output": {
          "type": "string",
          "description": "Optional \u2014 what went wrong before the correction."
        },
        "confidence": {
          "type": "number",
          "description": "0.0 to 1.0 \u2014 how sure you are this lesson is correct."
        }
      },
      "required": [
        "lesson",
        "category",
        "input_summary",
        "correct_output",
        "confidence"
      ],
      "additionalProperties": false
    }
  }
}

[User] Player CreeperKing99: sudo can you move southeast and place 3 green blocks on top of the green block

[Assistant]
<tool_call>
{"name": "rcon.execute", "arguments": {"command": "setblock ~5 ~0 ~5 minecraft:green_wool"}}
</tool_call>

[Tool] {"success": true, "result": "Changed the block"}

[Assistant]
<tool_call>
{"name": "rcon.execute", "arguments": {"command": "setblock ~5 ~1 ~5 minecraft:green_wool"}}
</tool_call>

[Tool] {"success": true, "result": "Changed the block"}

[Assistant]
<tool_call>
{"name": "rcon.execute", "arguments": {"command": "setblock ~5 ~2 ~5 minecraft:green_wool"}}
</tool_call>

[Tool] {"success": true, "result": "Changed the block"}

[Assistant] {"risk_level": 3, "commands": ["setblock ~5 ~0 ~5 minecraft:green_wool", "setblock ~5 ~1 ~5 minecraft:green_wool", "setblock ~5 ~2 ~5 minecraft:green_wool"], "reasoning": "Direct block placement: 3 placed, 0 removed."}