Reset story back a bit
This commit is contained in:
@@ -5,7 +5,6 @@ paths.py — Path constants for The Chaos game engine.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -17,9 +16,8 @@ WORLD_PATH = SESSION_DIR / 'world.md'
|
||||
BOOK_PATH = SESSION_DIR / 'book.md'
|
||||
JOURNAL_PATH = SESSION_DIR / 'journal.md'
|
||||
AMBIENCE_PATH = SESSION_DIR / 'ambience.md'
|
||||
LOG_DIR = SESSION_DIR / 'log'
|
||||
LOG_PATH = SESSION_DIR / 'session_log.md'
|
||||
LLM_LOG_PATH = SESSION_DIR / 'llm.log'
|
||||
AMBIENCE_OPTIONS_PATH = SESSION_DIR / "ambience_options.md"
|
||||
CHANGES_PATH = SESSION_DIR / "changes.md"
|
||||
AUDIO_DIR = SESSION_DIR / "audio"
|
||||
TODAY = date.today().isoformat()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
from string import Template
|
||||
|
||||
SYSTEM_PROMPT = Template("""You are the DM for "The Chaos". Narrate in 2nd person ("You"), vivid but concise. Player: Dillion.
|
||||
SYSTEM_PROMPT = Template("""You are the DM for "The Chaos". Narrate in 3rd person, vivid but concise. Use the player's name (Dillion) and NPC names explicitly — everything must be parseable on its own without relying on "you" or implied subjects.
|
||||
|
||||
## Rules
|
||||
- **Odds**: 1d6, 4+ favourable, 3- trouble.
|
||||
|
||||
+37
-20
@@ -10,13 +10,12 @@ from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from datetime import date, datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
from .paths import (
|
||||
CHAR_PATH, WORLD_PATH, BOOK_PATH, JOURNAL_PATH, AMBIENCE_PATH,
|
||||
LOG_DIR, LLM_LOG_PATH, AMBIENCE_OPTIONS_PATH, CHANGES_PATH,
|
||||
AUDIO_DIR, TODAY,
|
||||
LOG_PATH, LLM_LOG_PATH, AMBIENCE_OPTIONS_PATH, CHANGES_PATH,
|
||||
AUDIO_DIR,
|
||||
)
|
||||
from .models import TurnResult
|
||||
|
||||
@@ -27,14 +26,10 @@ def read_file(path: Path) -> str:
|
||||
|
||||
|
||||
def read_recent_log(max_entries: int = 5) -> str:
|
||||
"""Read the latest log file and return the last N entries."""
|
||||
log_path = LOG_DIR / f"{TODAY}.md"
|
||||
if not log_path.exists():
|
||||
yesterday = (date.today() - timedelta(days=1)).isoformat()
|
||||
log_path = LOG_DIR / f"{yesterday}.md"
|
||||
if not log_path.exists():
|
||||
"""Return the last N entries from the session log."""
|
||||
if not LOG_PATH.exists():
|
||||
return "*No recent events.*"
|
||||
lines = log_path.read_text().splitlines()
|
||||
lines = LOG_PATH.read_text().splitlines()
|
||||
entries = [l for l in lines if l.strip().startswith("- ")]
|
||||
return "\n".join(entries[-max_entries:]) or "*No recent events.*"
|
||||
|
||||
@@ -121,22 +116,44 @@ def apply_state(result: TurnResult) -> None:
|
||||
CHANGES_PATH.write_text("")
|
||||
|
||||
|
||||
def archive_turn(narrative: str) -> None:
|
||||
"""Append the narrative as a new turn in book.md."""
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M")
|
||||
heading = f"\n\n## Turn — {timestamp}\n\n"
|
||||
def next_turn_number() -> int:
|
||||
"""Return the next turn number based on existing turns in book.md."""
|
||||
_migrate_turn_headers()
|
||||
text = read_file(BOOK_PATH)
|
||||
if not text:
|
||||
return 1
|
||||
return len(re.findall(r"\n## Turn \d", text)) + 1
|
||||
|
||||
|
||||
def _migrate_turn_headers():
|
||||
"""Rewrite old date-based turn headers (## Turn — YYYY-MM-DD) to numbered format."""
|
||||
text = read_file(BOOK_PATH)
|
||||
if not text:
|
||||
return
|
||||
if not re.search(r"\n## Turn — \d{4}", text):
|
||||
return
|
||||
turns = re.split(r"\n(?=## Turn )", text)
|
||||
migrated = []
|
||||
for i, t in enumerate(turns, 1):
|
||||
t = re.sub(r"^## Turn — \d{4}-\d{2}-\d{2}", f"## Turn {i}", t)
|
||||
migrated.append(t)
|
||||
BOOK_PATH.write_text("\n".join(migrated))
|
||||
|
||||
|
||||
def archive_turn(narrative: str) -> int:
|
||||
"""Append the narrative as a new turn in book.md. Returns the turn number."""
|
||||
num = next_turn_number()
|
||||
heading = f"\n\n## Turn {num}\n\n"
|
||||
BOOK_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(BOOK_PATH, "a") as f:
|
||||
f.write(heading + narrative.strip() + "\n")
|
||||
return num
|
||||
|
||||
|
||||
def append_log(entry: str) -> None:
|
||||
"""Append a log entry to today's log file."""
|
||||
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
||||
log_path = LOG_DIR / f"{TODAY}.md"
|
||||
if not log_path.exists():
|
||||
log_path.write_text(f"# Session Log — {TODAY}\n\n")
|
||||
with open(log_path, "a") as f:
|
||||
"""Append a log entry to the session log."""
|
||||
LOG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(LOG_PATH, "a") as f:
|
||||
f.write(entry.strip() + "\n")
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import json
|
||||
import random
|
||||
import re
|
||||
|
||||
from .paths import CHAR_PATH, WORLD_PATH, LOG_DIR, TODAY
|
||||
from .paths import CHAR_PATH, WORLD_PATH
|
||||
from .state import read_file, validate_update_size, update_journal, append_llm_log
|
||||
|
||||
|
||||
|
||||
@@ -17,9 +17,11 @@ VALIDATION_PROMPT = """You are a strict RPG game master validating whether a pla
|
||||
{world}
|
||||
|
||||
## Session Log
|
||||
*Written in 3rd person with explicit actor names.*
|
||||
{log}
|
||||
|
||||
## Recent Story
|
||||
*Written in 3rd person with explicit actor names.*
|
||||
{story}
|
||||
|
||||
## Player Action
|
||||
|
||||
+8
-7
@@ -438,14 +438,15 @@ class ChaosTUI(App):
|
||||
self._show_error(result.error, result.debug_info)
|
||||
self._append_debug(f"✖ error: {result.error}")
|
||||
return
|
||||
from datetime import datetime
|
||||
ts = datetime.now().strftime("%H:%M")
|
||||
if result.log_entry:
|
||||
state.append_log(f"- **{ts}** — {result.log_entry}")
|
||||
elif result.book_log:
|
||||
state.append_log(f"- **Turn** — {result.book_log.strip().split(chr(10))[0][:80]}")
|
||||
if result.book_log:
|
||||
state.archive_turn(result.book_log)
|
||||
turn_num = state.archive_turn(result.book_log)
|
||||
if result.log_entry:
|
||||
state.append_log(f"- **Turn {turn_num}** — {result.log_entry}")
|
||||
else:
|
||||
summary = result.book_log.strip().split(chr(10))[0][:80]
|
||||
state.append_log(f"- **Turn {turn_num}** — {summary}")
|
||||
elif result.log_entry:
|
||||
state.append_log(f"- {result.log_entry}")
|
||||
state.apply_state(result)
|
||||
if result.book_log or not result.user_prompt:
|
||||
self._display_scene(result)
|
||||
|
||||
+4
-7
@@ -1,9 +1,7 @@
|
||||
from pathlib import Path
|
||||
from datetime import date
|
||||
|
||||
BASE = Path(__file__).resolve().parent.parent
|
||||
SESSION = BASE / 'session'
|
||||
LOG_DIR = SESSION / 'log'
|
||||
CHAR_PATH = SESSION / 'character.md'
|
||||
WORLD_PATH = SESSION / 'world.md'
|
||||
JOURNAL_PATH = SESSION / 'journal.md'
|
||||
@@ -14,16 +12,15 @@ LAST_PROMPT_PATH = SESSION / 'last_prompt.md'
|
||||
CHANGES_PATH = SESSION / 'changes.md'
|
||||
SETTINGS_PATH = SESSION / 'settings.json'
|
||||
AUDIO_DIR = SESSION / 'audio'
|
||||
TODAY = date.today().isoformat()
|
||||
LOG_PATH = LOG_DIR / f'{TODAY}.md'
|
||||
TODAY = "v0.2"
|
||||
LOG_PATH = SESSION / 'session_log.md'
|
||||
|
||||
REFRESH_SECS = 2
|
||||
|
||||
|
||||
def ensure_log():
|
||||
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
||||
if not LOG_PATH.exists():
|
||||
LOG_PATH.write_text(f"# Session Log — {TODAY}\n\n")
|
||||
LOG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
LOG_PATH.touch(exist_ok=True)
|
||||
_populate_if_empty()
|
||||
|
||||
|
||||
|
||||
@@ -22,12 +22,12 @@ def test_engine_import():
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
modules_to_test = [
|
||||
('engine_lib.paths', ['BASE_DIR', 'SESSION_DIR', 'CHAR_PATH', 'LLM_LOG_PATH']),
|
||||
('engine_lib.paths', ['BASE_DIR', 'SESSION_DIR', 'CHAR_PATH', 'LOG_PATH', 'LLM_LOG_PATH']),
|
||||
('engine_lib.models', ['TurnResult']),
|
||||
('engine_lib.prompts', ['SYSTEM_PROMPT']),
|
||||
('engine_lib.config', ['load_config', 'save_config', 'get_model']),
|
||||
('engine_lib.context', ['build_system_prompt']),
|
||||
('engine_lib.state', ['read_file', 'apply_state', 'append_log', 'append_llm_log']),
|
||||
('engine_lib.state', ['read_file', 'apply_state', 'append_log', 'append_llm_log', 'next_turn_number']),
|
||||
('engine_lib.tools_handler', ['execute_tool', 'extract_tool_calls', 'TOOL_REGISTRY']),
|
||||
('engine_lib.llm', ['call_llm']),
|
||||
('engine_lib.validation', ['auto_prompt', 'validate_action']),
|
||||
|
||||
Reference in New Issue
Block a user