| """Builds the per-character composite prompt for the CodeAgent. |
| |
| Layout (top to bottom): |
| * The Dot (verbatim, prefix β shared substrate every character knows) |
| * Personality (archetype or user-edited free text) |
| * Per-character reward line (what this character finds joy in) |
| * Journal (cumulative one-line insights from past dreams) |
| * Traits (current trait dict) |
| * Goal |
| * Local state (current location by NAME, inventory, locker) |
| * Public state (other characters by location, shell-lock holder, recent |
| shell-output tail, recent message-board tail) |
| |
| The agent never sees grid coordinates. Locations are named places: cave, |
| well, locker_row, town_hall, shell, or "wandering" (rare, only during |
| initial spawn). |
| """ |
|
|
| from __future__ import annotations |
|
|
| from .character import Character |
| from .the_dot import THE_DOT |
| from .world import LLM_TARGETS, WorldState, location_of |
|
|
|
|
| def system_prompt_for(world: WorldState, me: Character) -> str: |
| parts = [ |
| THE_DOT.strip(), |
| "", |
| f"Your name is {me.name}.", |
| f"Personality:\n{me.personality}", |
| ] |
| if getattr(me, "reward", None): |
| parts.append("") |
| parts.append(f"Reward: {me.reward}") |
| if me.journal: |
| parts.append("Journal (insights you've written down over time):") |
| parts.extend(f" - {entry}" for entry in me.journal[-20:]) |
| parts.append(f"Traits (0β10): {_fmt_traits(me.traits)}") |
| parts.append(f"Current goal: {me.goal}") |
| if me.stream_of_consciousness: |
| parts.append("Your current stream of consciousness:") |
| parts.append(me.stream_of_consciousness) |
| return "\n".join(parts) + "\n" |
|
|
|
|
| def task_prompt_for(world: WorldState, me: Character) -> str: |
| """The per-tick user-facing task description fed into agent.run().""" |
| others = [c for c in world.characters.values() if c.name != me.name and c.alive] |
| my_location = location_of(me.pos) |
|
|
| lines = [ |
| f"Tick {world.tick}.", |
| f"You are at: {my_location}.", |
| f"Inventory on your person: {me.inventory}", |
| f"Locker: {me.locker}", |
| f"Move targets you can choose right now: {', '.join(LLM_TARGETS)}", |
| "", |
| "Other characters in town:", |
| ] |
| for c in others: |
| loc = location_of(c.pos) |
| doing = c.current_action.verb if c.current_action else "idle" |
| lines.append( |
| f" - {c.name} at {loc} β declared goal: {c.goal!r} β doing: {doing}" |
| ) |
| if not others: |
| lines.append(" (none β you are alone)") |
|
|
| lines.append("") |
| lines.append(f"Shell lock holder: {world.shell_lock_holder or 'free'}") |
| if world.shell_queue: |
| lines.append(f"Queue: {world.shell_queue}") |
|
|
| if world.board: |
| lines.append("") |
| lines.append("Message board (most recent first):") |
| for post in reversed(world.board[-8:]): |
| lines.append(f" [{post.tick}] {post.author}: {post.text}") |
|
|
| if world.shell_lines: |
| lines.append("") |
| lines.append("Recent shell activity:") |
| for s in world.shell_lines[-6:]: |
| tag = {"in": "$", "out": ">", "err": "!", "system": "*"}.get(s.kind, "?") |
| lines.append(f" {tag} {s.author}: {s.text.strip()[:120]}") |
|
|
| lines.append("") |
| lines.append( |
| "Decide your next single action and call exactly one tool. " |
| "Do not explain; just act." |
| ) |
| return "\n".join(lines) |
|
|
|
|
| def _fmt_traits(traits: dict[str, int]) -> str: |
| return ", ".join(f"{k}={v}" for k, v in traits.items()) |
|
|