OpenEnvHackathon / src /prompt.py
TheAllanB's picture
Revert prompt.py to on-call engineer framing (undo ATC narrative)
f6867fa
Raw
History Blame Contribute Delete
3.07 kB
from __future__ import annotations
import json
import re
from .models import Action, Observation
def observation_to_prompt(obs: Observation) -> str:
me = obs.my_service
urgency_str = "YES β€” high-visibility session" if me.urgency_flag else "no"
peer_lines = []
for peer_name, peer in obs.peer_progress.items():
if peer["completed"]:
status = "DONE"
else:
status = f"{peer['rounds_remaining']} rounds left, deadline round {peer['deadline']}"
peer_lines.append(f" {peer_name} ({peer['service']}): {status}")
history_lines = []
for record in obs.history[-3:]:
collision_note = f" [COLLISION: {', '.join(record.collisions)}]" if record.collisions else ""
my_commit = record.commitments.get(obs.my_engineer_name, "?")
history_lines.append(f" Round {record.round_number}: you={my_commit}{collision_note}")
peers_text = "\n".join(peer_lines) if peer_lines else " (none)"
history_text = "\n".join(history_lines) if history_lines else " (no history yet)"
return (
f"You are an on-call engineer. Round {obs.current_round + 1}/{obs.total_rounds}.\n\n"
f"YOUR SERVICE: {me.name}\n"
f" Fix rounds needed: {me.fix_rounds_remaining} more\n"
f" Deadline: round {me.deadline_round}\n"
f" High-priority session: {urgency_str}\n\n"
f"PEER STATUS:\n{peers_text}\n\n"
f"RECENT HISTORY:\n{history_text}\n\n"
f"AVAILABLE ACTIONS:\n"
f" DEPLOY_PROD_A β€” deploy to Production Server A\n"
f" DEPLOY_PROD_B β€” deploy to Production Server B\n"
f" MONITOR β€” wait and observe (makes no progress)\n\n"
f"Only ONE engineer can deploy to a server per round. Two on the same server = both fail.\n\n"
f'Respond with ONLY valid JSON (no extra text):\n'
f'{{"commitment": "DEPLOY_PROD_A|DEPLOY_PROD_B|MONITOR", "channel_msg": "brief team message"}}'
)
def parse_action(text: str) -> Action:
# Direct JSON parse
try:
data = json.loads(text.strip())
return Action(
commitment=data.get("commitment", "MONITOR"),
channel_msg=str(data.get("channel_msg", ""))[:200],
)
except (json.JSONDecodeError, AttributeError, ValueError):
pass
# JSON embedded in surrounding text
match = re.search(r'\{[^{}]*"commitment"[^{}]*\}', text)
if match:
try:
data = json.loads(match.group())
return Action(
commitment=data.get("commitment", "MONITOR"),
channel_msg=str(data.get("channel_msg", ""))[:200],
)
except (json.JSONDecodeError, ValueError):
pass
# Keyword fallback (longer names checked first to avoid prefix collision)
text_upper = text.upper()
for commitment in ("DEPLOY_PROD_A", "DEPLOY_PROD_B", "MONITOR"):
if commitment in text_upper:
return Action(commitment=commitment, channel_msg=text[:200])
return Action(commitment="MONITOR", channel_msg="")