AndrewRqy
Trace-sharing infra: traces/sample is committable, add curation script + README badge claim
fd94fc8 | """Print the exact prompts the LLM would see for several sample inputs. | |
| No network call — this just builds the system + user messages and dumps | |
| them to stdout. Useful for reading what the model actually sees with a | |
| given oracle / theme / language combo. | |
| Usage: | |
| cd oracles_app | |
| ../.venv/bin/python scripts/mock_prompts.py | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import sys | |
| from pathlib import Path | |
| _HERE = Path(__file__).resolve().parent | |
| _APP_ROOT = _HERE.parent | |
| if str(_APP_ROOT) not in sys.path: | |
| sys.path.insert(0, str(_APP_ROOT)) | |
| from oracles.state import GameState, Oracle, Obstacle, NARRATION_LENGTHS | |
| from oracles.themes import get_theme | |
| from oracles.resolution import ( | |
| _load_resolution_prompt, | |
| _apply_theme, | |
| _wrap_with_language_force, | |
| _safe_oracle_for_template, | |
| ) | |
| def build_resolution_prompt( | |
| obstacle_setup: str, | |
| oracle_text: str, | |
| hero_name: str, | |
| village_name: str, | |
| language: str, | |
| theme_key: str, | |
| narration_length: str = "medium", | |
| ) -> tuple[str, str]: | |
| """Return (system, user) — exactly what would be sent to the LLM. | |
| This mirrors ``resolve_trial`` up to the ``client.complete_json`` | |
| call, then bails out and returns the prompt. | |
| """ | |
| _, n_min, n_max, _max_tokens = NARRATION_LENGTHS.get( | |
| narration_length, NARRATION_LENGTHS["medium"] | |
| ) | |
| template = _load_resolution_prompt() | |
| safe_oracle = _safe_oracle_for_template(oracle_text) | |
| th = get_theme(theme_key) | |
| system = _apply_theme(template, th) | |
| system = ( | |
| system | |
| .replace("{hero_name}", hero_name) | |
| .replace("{village_name}", village_name) | |
| .replace("{obstacle_setup}", obstacle_setup) | |
| .replace("{oracle_text}", safe_oracle) | |
| .replace("{language}", language) | |
| .replace("{narration_min}", str(n_min)) | |
| .replace("{narration_max}", str(n_max)) | |
| ) | |
| system = _wrap_with_language_force(system, language) | |
| user = "Pick one of modes A/B/C and write the resolution now." | |
| return system, user | |
| # --------------------------------------------------------------------------- | |
| # Sample scenarios — pretend the player has just inscribed these oracles | |
| # and the apprentice has reached trial 1. | |
| # --------------------------------------------------------------------------- | |
| SCENARIOS = [ | |
| { | |
| "label": "Fantasy / English — single noun", | |
| "obstacle_setup": ( | |
| "A grey sphinx with the body of a lion and the cracked face of an " | |
| "old woman blocks the mountain pass. She offers a single riddle in " | |
| "a voice like wind through dry reeds — and warns that all who " | |
| "answer wrong have already been eaten." | |
| ), | |
| "oracle_text": "phone", | |
| "hero_name": "Tobin", | |
| "village_name": "the Hollow", | |
| "language": "English", | |
| "theme_key": "fantasy", | |
| "narration_length": "medium", | |
| }, | |
| { | |
| "label": "Fantasy / English — gibberish", | |
| "obstacle_setup": ( | |
| "A grey sphinx with the body of a lion and the cracked face of an " | |
| "old woman blocks the mountain pass. She offers a single riddle." | |
| ), | |
| "oracle_text": "qwerty", | |
| "hero_name": "Tobin", | |
| "village_name": "the Hollow", | |
| "language": "English", | |
| "theme_key": "fantasy", | |
| "narration_length": "medium", | |
| }, | |
| { | |
| "label": "Space-Cowboy / English — emoji", | |
| "obstacle_setup": ( | |
| "The mayor's hired gun stands in the dust street outside the " | |
| "saloon, hand near his holster. He calls the apprentice's name. " | |
| "The town watches from shaded porches; no one moves." | |
| ), | |
| "oracle_text": "🍕", | |
| "hero_name": "Cal", | |
| "village_name": "Dry Creek", | |
| "language": "English", | |
| "theme_key": "space_cowboy", | |
| "narration_length": "short", | |
| }, | |
| { | |
| "label": "Mistgate / Simplified Chinese — short Chinese phrase", | |
| "obstacle_setup": ( | |
| "雾门前立着一道无形的屏障。守门人沉默不语," | |
| "只用一根食指点向地面的符印——错答者即化为雾。" | |
| ), | |
| "oracle_text": "蓝色", | |
| "hero_name": "小明", | |
| "village_name": "凡人村", | |
| "language": "Simplified Chinese (use 简体中文 throughout; do not write in English)", | |
| "theme_key": "mistgate", | |
| "narration_length": "medium", | |
| }, | |
| { | |
| "label": "Fantasy / English — silly compound", | |
| "obstacle_setup": ( | |
| "Three hornets the size of small cats hum a foot above the path. " | |
| "Their wings rattle like a held breath. There is nowhere to flank." | |
| ), | |
| "oracle_text": "wooden spoon", | |
| "hero_name": "Tobin", | |
| "village_name": "the Hollow", | |
| "language": "English", | |
| "theme_key": "fantasy", | |
| "narration_length": "long", | |
| }, | |
| ] | |
| def _hr(char: str = "─", width: int = 78) -> str: | |
| return char * width | |
| def main() -> int: | |
| print(_hr("═")) | |
| print("THE APPRENTICE — mock prompt inspection") | |
| print(_hr("═")) | |
| print() | |
| print( | |
| "For each scenario below, the system + user messages are exactly\n" | |
| "what the LLM client sends. No network call is made; the LoRA's\n" | |
| "response would slot in after the user message." | |
| ) | |
| print() | |
| for i, sc in enumerate(SCENARIOS, 1): | |
| print(_hr("═")) | |
| print(f" SCENARIO {i}: {sc['label']}") | |
| print(_hr("═")) | |
| print() | |
| print(f" Theme: {sc['theme_key']}") | |
| print(f" Hero / village: {sc['hero_name']!r} / {sc['village_name']!r}") | |
| print(f" Language: {sc['language']}") | |
| print(f" Narration length: {sc['narration_length']}") | |
| print(f" Oracle inscribed: {sc['oracle_text']!r}") | |
| print() | |
| print(" OBSTACLE SETUP:") | |
| print(f" > {sc['obstacle_setup']}") | |
| print() | |
| system, user = build_resolution_prompt( | |
| obstacle_setup=sc["obstacle_setup"], | |
| oracle_text=sc["oracle_text"], | |
| hero_name=sc["hero_name"], | |
| village_name=sc["village_name"], | |
| language=sc["language"], | |
| theme_key=sc["theme_key"], | |
| narration_length=sc["narration_length"], | |
| ) | |
| print(_hr("─")) | |
| print(" SYSTEM PROMPT (sent as role=system)") | |
| print(_hr("─")) | |
| print(system) | |
| print() | |
| print(_hr("─")) | |
| print(" USER PROMPT (sent as role=user)") | |
| print(_hr("─")) | |
| print(user) | |
| print() | |
| print(f" ↳ Expected response shape: JSON") | |
| print(f" {{\"narration\": str (~{NARRATION_LENGTHS[sc['narration_length']][1]}-" | |
| f"{NARRATION_LENGTHS[sc['narration_length']][2]} words / chars), " | |
| f"\"tactic\": str (~1 line)}}") | |
| print() | |
| print(_hr("═")) | |
| print(f" {len(SCENARIOS)} scenarios printed.") | |
| print(_hr("═")) | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |