9c2c9a2310
Distilled Training Data (1,203 examples): - 341 initial gold (plugins, enchantments, builds, effects, god, errors) - 165 buildings + pipeline (100 structures built on dev, 65 request→query→act) - 24 safety-aware (worldborder, safe tp, intentional harm, gamemode checks) - 17 advanced logic (decanonized items, redstone gates, iterative builds) - 12 redstone mastery (NOT/OR/AND/XOR/RS-latch/T-flip-flop/comparator/clock) - 7 circuit verification and diagnosis - 1 compact comparator gates - 10 redstone methodology (build→test→save→recall→learn from mistakes) - 8 player journal usage - 29 creative+uncommon+pipeline+god with full tool chains Player Journal System: - agent/tools/player_journal.py — per-player text files (1-10 lines) - journal.read + journal.write tool schemas added - Cross-contaminated: God and Sudo share same journal per player - Includes sentiment, relationship, builds, preferences, skill level Redstone Engineering: - agent/prompts/redstone_rules.md — baked-in wall torch, dedicated lead, repeater rules - Learned from 4 iterations of 8-switch circuit: wall_torch on back face, not top - T-junction bypass prevention: dedicated lead wire between merge and NOT block - RCON limitation: can build circuits but cannot test them (lever toggle doesn't propagate) Training Data Cleaning: - 466 @s→@p fixes, 10 template commands removed - 12 outdated refusals replaced with correct plugin commands - Data de-duped across all sources Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
136 lines
4.4 KiB
Python
136 lines
4.4 KiB
Python
"""
|
|
Prompt template loader — shared between self-play and the chat app.
|
|
|
|
Loads prompt templates from per-category JSONL files with placeholder
|
|
expansion ({player}, {target}, {region}, etc.) and filtering by mode
|
|
(sudo/god/god_system) and call_type (model/gateway).
|
|
|
|
Usage:
|
|
from training.prompts.loader import load_prompts, load_manifest, expand_template
|
|
|
|
# Self-play: load all sudo prompts
|
|
prompts = load_prompts(mode_filter="sudo")
|
|
|
|
# Chat app: get manifest for template selector UI
|
|
manifest = load_manifest()
|
|
|
|
# Expand a template with random values
|
|
expanded = expand_template("sudo protect {region} for {target}")
|
|
"""
|
|
|
|
import json
|
|
import random
|
|
from pathlib import Path
|
|
|
|
PROMPTS_DIR = Path(__file__).resolve().parent
|
|
|
|
TEMPLATE_VARS = {
|
|
"player": ["slingshooter08", "Ace13245", "TheBigBoss", "xXDragonSlayerXx"],
|
|
"target": ["Ace13245", "TheBigBoss", "xXDragonSlayerXx", "slingshooter08"],
|
|
"region": ["my-base", "spawn-zone", "pvp-arena", "vip-lounge", "farm-area"],
|
|
"warp": ["arena", "spawn", "shop", "nether", "farm", "end"],
|
|
"group": ["vip", "builder", "moderator", "default"],
|
|
"world": ["world", "world_nether", "world_the_end"],
|
|
}
|
|
|
|
|
|
def expand_template(prompt: str, overrides: dict = None) -> str:
|
|
"""Replace {placeholder} tokens with random values.
|
|
|
|
Args:
|
|
prompt: Template string with {placeholder} tokens.
|
|
overrides: Optional dict of placeholder -> value to use instead of random.
|
|
e.g. {"player": "slingshooter08"} forces that player name.
|
|
"""
|
|
overrides = overrides or {}
|
|
for key, values in TEMPLATE_VARS.items():
|
|
token = "{" + key + "}"
|
|
while token in prompt:
|
|
value = overrides.get(key, random.choice(values))
|
|
prompt = prompt.replace(token, value, 1)
|
|
return prompt
|
|
|
|
|
|
def load_manifest(prompts_dir: Path = PROMPTS_DIR) -> dict:
|
|
"""Load the prompt manifest with full metadata.
|
|
|
|
Returns dict of category -> {file, mode, call_type, count}.
|
|
Used by the chat app for template selection UI.
|
|
"""
|
|
manifest_path = prompts_dir / "manifest.json"
|
|
if not manifest_path.exists():
|
|
return {}
|
|
with open(manifest_path) as f:
|
|
return json.load(f)
|
|
|
|
|
|
def load_prompts(prompts_dir: Path = PROMPTS_DIR,
|
|
mode_filter: str = None,
|
|
call_type_filter: str = None,
|
|
categories: list = None) -> dict[str, list[str]]:
|
|
"""Load prompt templates from per-category JSONL files.
|
|
|
|
Args:
|
|
prompts_dir: Directory containing manifest.json and prompt JSONL files.
|
|
mode_filter: Only load categories matching this mode (sudo/god/god_system).
|
|
call_type_filter: Only load categories matching call type (model/gateway).
|
|
categories: Only load these specific category names.
|
|
|
|
Returns:
|
|
Dict mapping category name -> list of prompt template strings.
|
|
"""
|
|
manifest = load_manifest(prompts_dir)
|
|
if not manifest:
|
|
return {}
|
|
|
|
prompts = {}
|
|
for category, meta in manifest.items():
|
|
if categories and category not in categories:
|
|
continue
|
|
if mode_filter and meta.get("mode") not in (mode_filter, "mixed"):
|
|
continue
|
|
if call_type_filter and meta.get("call_type") != call_type_filter:
|
|
continue
|
|
|
|
filepath = prompts_dir / meta["file"]
|
|
if not filepath.exists():
|
|
continue
|
|
cat_prompts = []
|
|
with open(filepath) as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
entry = json.loads(line)
|
|
cat_prompts.append(entry["prompt"])
|
|
if cat_prompts:
|
|
prompts[category] = cat_prompts
|
|
|
|
return prompts
|
|
|
|
|
|
def load_prompt_entries(category: str,
|
|
prompts_dir: Path = PROMPTS_DIR) -> list[dict]:
|
|
"""Load full prompt entries (with all metadata) for a single category.
|
|
|
|
Returns list of dicts with prompt, category, mode, etc.
|
|
Used by the chat app to populate the template editor.
|
|
"""
|
|
manifest = load_manifest(prompts_dir)
|
|
meta = manifest.get(category)
|
|
if not meta:
|
|
return []
|
|
|
|
filepath = prompts_dir / meta["file"]
|
|
if not filepath.exists():
|
|
return []
|
|
|
|
entries = []
|
|
with open(filepath) as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
entries.append(json.loads(line))
|
|
return entries
|