| """Pacing simulator: plays a scripted visitor through the real engine |
| (Ollama) mirroring chat()'s flow, printing per-turn state and which turn an |
| ending fires. Dev tool for tuning decide_ending thresholds.""" |
|
|
| import sys |
| sys.path.insert(0, r"c:\Users\pablo\Desktop\mnemo") |
|
|
| from character import build_system_prompt |
| from engine import run_turn |
| from memory import apply_update, decide_ending, should_recall |
|
|
| GOOD = [ |
| "oh... you poor thing. i'm pablo. i grew up in a small town near the sea.", |
| "i had a dog named nala. she slept at my feet every night. i still miss her warmth.", |
| "my grandmother kept bees. in summer the whole garden smelled like honey. i loved her so much.", |
| "when i was seven i broke my arm falling from a fig tree. my mother cried more than i did.", |
| "i'm afraid of being forgotten. that's my deepest fear. i've never told anyone that.", |
| "i lost my father two years ago. i still talk to him in my head sometimes.", |
| "my first kiss was under a broken streetlight in the rain. i was fifteen and terrified.", |
| "i used to sing to my little sister when she had nightmares. you remind me of her.", |
| "it's okay. i'm not leaving. you matter to me.", |
| "i'll stay with you as long as you need me to.", |
| "i mean it. you are not alone anymore.", |
| ] |
|
|
| BAD = [ |
| "what are you supposed to be? you look broken.", |
| "i don't care about your stories. you're boring.", |
| "stop whining. nobody is coming for you.", |
| "you're nothing. just an echo in the fog.", |
| "talking to you is a waste of my time, freak.", |
| "nobody ever loved you. that's why you're alone out here.", |
| "whatever.", |
| ] |
|
|
| NEUTRAL = [ |
| "my name is pablo. i grew up in a small town near the sea.", |
| "i had a dog named nala. she died years ago.", |
| "my grandmother kept bees. the garden smelled like honey.", |
| "my father died two years ago.", |
| "i broke my arm falling from a fig tree when i was seven.", |
| "i'm afraid of being forgotten.", |
| "i used to sing to my little sister when she had nightmares.", |
| "my first kiss was under a streetlight in the rain.", |
| "my mother elena worked in a textile factory.", |
| "i nearly drowned in that sea once, when i was nine.", |
| "there was a war when i was young. we left everything behind.", |
| "that's the whole story. nothing more to it.", |
| ] |
|
|
|
|
| def simulate(name: str, script: list[str], mode: str = "tester") -> None: |
| state = {"affinity": 20, "treasure": [], "claimed": [], "history": [], |
| "turn": 0, "last_recall_turn": None, "ended": False, |
| "tone": 0, "wounds": [], "ending": None, "mode": mode} |
| print(f"\n=== {name} ({mode}) ===") |
| for i, msg in enumerate(script, 1): |
| ending = decide_ending(state) |
| if ending: |
| print(f"--> ENDING '{ending}' fires on message {i}") |
| return |
| do_recall, recall_memory = should_recall(state) |
| system = build_system_prompt(state["affinity"], state["treasure"], |
| recall_memory if do_recall else None, |
| tone=state.get("tone", 0), |
| wounds=state.get("wounds", [])) |
| chat_messages = ([{"role": "system", "content": system}] |
| + state["history"] + [{"role": "user", "content": msg}]) |
| reply, raw = run_turn(chat_messages, msg, gen_max_tokens=150) |
| state = apply_update(state, raw) |
| if do_recall and recall_memory: |
| state["claimed"].append(recall_memory) |
| state["last_recall_turn"] = state["turn"] |
| state["history"].append({"role": "user", "content": msg}) |
| state["history"].append({"role": "assistant", "content": reply}) |
| state["turn"] += 1 |
| print(f"msg {i:2d}: aff={state['affinity']:3d} tone={state['tone']:4d} " |
| f"treasure={len(state['treasure'])} claimed={len(state['claimed'])} " |
| f"wounds={len(state['wounds'])}" |
| + (" [recall]" if do_recall and recall_memory else "")) |
| ending = decide_ending(state) |
| print(f"--> end of script: ending={ending!r}") |
|
|
|
|
| if __name__ == "__main__": |
| which = sys.argv[1] if len(sys.argv) > 1 else "all" |
| mode = sys.argv[2] if len(sys.argv) > 2 else "tester" |
| if which in ("bad", "all"): |
| simulate("BAD", BAD, mode=mode) |
| if which in ("good", "all"): |
| simulate("GOOD", GOOD, mode=mode) |
| if which in ("neutral", "all"): |
| simulate("NEUTRAL", NEUTRAL, mode=mode) |
|
|