Validate speech and disable dice rolls

This commit is contained in:
Dejvino
2026-07-04 15:52:22 +02:00
parent 527369f280
commit a0d24c9d44
7 changed files with 5 additions and 131 deletions
-6
View File
@@ -19,12 +19,6 @@ Output ONLY ```tool blocks — no prose, no reasoning, no explanation outside to
Wrap each action in its own ```tool block:
```tool
{"tool": "roll", "args": {"dice": "1d6"}}
```
```tool
{"tool": "player_roll", "args": {"dice": "1d6", "reason": "a check"}}
```
```tool
{"tool": "modify_vitals", "args": {"current_hp": 5, "cash": 45}}
```
-25
View File
@@ -1,7 +1,6 @@
from __future__ import annotations
import json
import random
import re
from .paths import AMBIENCE_PATH, CHAR_PATH, WORLD_PATH
@@ -9,8 +8,6 @@ from .state import read_file, validate_update_size, update_journal, append_llm_l
TOOL_REGISTRY: dict[str, dict] = {
"roll": {"description": "Roll dice.", "args": {"dice": "1d6", "modifier": "+1"}},
"player_roll": {"description": "Ask player to roll.", "args": {"dice": "1d6", "reason": "why"}},
"modify_traits": {"description": "Change STR/DEX/WIL.", "args": {"str": "optional", "dex": "optional", "wil": "optional"}},
"modify_vitals": {"description": "Change HP, cash, weapon, armour.", "args": {"current_hp": "optional", "max_hp": "optional", "cash": "optional", "weapon": "optional", "armour": "optional"}},
"add_to_inventory": {"description": "Add item to gear.", "args": {"item": "item name and stats"}},
@@ -34,27 +31,6 @@ def patch_character(pattern: str, repl: str, count: int = 1, flags: int = 0) ->
return ""
def tool_roll(args: dict) -> str:
dice_str = (args or {}).get("dice", "1d6")
modifier_str = (args or {}).get("modifier", "0")
try:
count, sides = dice_str.lower().split("d")
count = int(count) if count else 1
sides = int(sides)
except (ValueError, TypeError):
return f"Invalid dice: {dice_str}. Use format like '2d6'."
mod = 0
if modifier_str:
try:
mod = int(modifier_str)
except ValueError:
pass
rolls = [random.randint(1, sides) for _ in range(count)]
total = sum(rolls) + mod
mod_str = f" {'+' if mod >= 0 else ''}{mod}" if mod != 0 else ""
return f"Roll: {dice_str}{mod_str} → [{', '.join(str(r) for r in rolls)}] = {total}"
def tool_modify_traits(args: dict) -> str:
errors = []
for stat in ("str", "dex", "wil"):
@@ -185,7 +161,6 @@ def tool_finalize_turn(args: dict) -> str:
def execute_tool(tool_name: str, args: dict) -> str:
"""Execute a tool by name. Returns result string."""
fn_map = {
"roll": tool_roll,
"modify_traits": tool_modify_traits,
"modify_vitals": tool_modify_vitals,
"add_to_inventory": tool_add_to_inventory,
+1
View File
@@ -103,6 +103,7 @@ TURN_VALIDATION_PROMPT = """You are a strict RPG game master validating a genera
4. **Self-Contained Narrative**: The narrative must read clearly on its own — explicitly describe what the character did in response to the action. Do not skip the character's action and jump straight to consequences. Each turn must make sense without referencing the player action line.
5. **Log Entry**: Does the log entry accurately summarise the narrative in 1-2 short, dense sentences? Should be specific, factual, and immediately readable.
6. **Journal Progress**: Are TODO items being addressed? If the narrative resolves an open TODO, the turn must call `journal_update` to mark it done. Unchecked items left stale too long may need prompting.
7. **Player Speech**: If the player action contains direct speech (quoted text like `"Hello"` or `'Hello'`), the narrative MUST include the player character speaking those words or equivalent dialogue. If the player's speech can be incorporated given the context, the turn should reflect it. Only skip if the speech is completely impossible given the situation.
## Character (before changes)
{character}