mirror of
https://github.com/GoodStartLabs/AI_Diplomacy.git
synced 2026-04-19 12:58:09 +00:00
Moving more environment variables to central config
This commit is contained in:
parent
540c2003e8
commit
aadedd6512
11 changed files with 103 additions and 314 deletions
|
|
@ -1,36 +1,39 @@
|
|||
"""
|
||||
Module for constructing prompts for LLM interactions in the Diplomacy game.
|
||||
"""
|
||||
import logging
|
||||
from typing import Dict, List, Optional, Any # Added Any for game type placeholder
|
||||
|
||||
import logging
|
||||
from typing import Dict, List, Optional, Any # Added Any for game type placeholder
|
||||
|
||||
from ..config import config
|
||||
from .utils import load_prompt, get_prompt_path
|
||||
from .possible_order_context import (
|
||||
generate_rich_order_context,
|
||||
generate_rich_order_context_xml,
|
||||
)
|
||||
import os
|
||||
from .game_history import GameHistory # Assuming GameHistory is correctly importable
|
||||
from .game_history import GameHistory # Assuming GameHistory is correctly importable
|
||||
|
||||
# placeholder for diplomacy.Game to avoid circular or direct dependency if not needed for typehinting only
|
||||
# from diplomacy import Game # Uncomment if 'Game' type hint is crucial and available
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG) # Or inherit from parent logger
|
||||
logger.setLevel(logging.DEBUG) # Or inherit from parent logger
|
||||
|
||||
# --- Home-center lookup -------------------------------------------
|
||||
HOME_CENTERS: dict[str, list[str]] = {
|
||||
"AUSTRIA": ["Budapest", "Trieste", "Vienna"],
|
||||
"ENGLAND": ["Edinburgh", "Liverpool", "London"],
|
||||
"FRANCE": ["Brest", "Marseilles", "Paris"],
|
||||
"GERMANY": ["Berlin", "Kiel", "Munich"],
|
||||
"ITALY": ["Naples", "Rome", "Venice"],
|
||||
"RUSSIA": ["Moscow", "Saint Petersburg", "Sevastopol", "Warsaw"],
|
||||
"TURKEY": ["Ankara", "Constantinople", "Smyrna"],
|
||||
"AUSTRIA": ["Budapest", "Trieste", "Vienna"],
|
||||
"ENGLAND": ["Edinburgh", "Liverpool", "London"],
|
||||
"FRANCE": ["Brest", "Marseilles", "Paris"],
|
||||
"GERMANY": ["Berlin", "Kiel", "Munich"],
|
||||
"ITALY": ["Naples", "Rome", "Venice"],
|
||||
"RUSSIA": ["Moscow", "Saint Petersburg", "Sevastopol", "Warsaw"],
|
||||
"TURKEY": ["Ankara", "Constantinople", "Smyrna"],
|
||||
}
|
||||
|
||||
|
||||
def build_context_prompt(
|
||||
game: Any, # diplomacy.Game object
|
||||
game: Any, # diplomacy.Game object
|
||||
board_state: dict,
|
||||
power_name: str,
|
||||
possible_orders: Dict[str, List[str]],
|
||||
|
|
@ -76,22 +79,14 @@ def build_context_prompt(
|
|||
year_phase = board_state["phase"] # e.g. 'S1901M'
|
||||
|
||||
# Decide which context builder to use.
|
||||
_use_simple = os.getenv("SIMPLE_PROMPTS", "0").lower() in {"1", "true", "yes"}
|
||||
_use_simple = config.SIMPLE_PROMPTS
|
||||
if _use_simple:
|
||||
possible_orders_context_str = generate_rich_order_context(
|
||||
game, power_name, possible_orders
|
||||
)
|
||||
possible_orders_context_str = generate_rich_order_context(game, power_name, possible_orders)
|
||||
else:
|
||||
possible_orders_context_str = generate_rich_order_context_xml(
|
||||
game, power_name, possible_orders
|
||||
)
|
||||
|
||||
possible_orders_context_str = generate_rich_order_context_xml(game, power_name, possible_orders)
|
||||
|
||||
if include_messages:
|
||||
messages_this_round_text = game_history.get_messages_this_round(
|
||||
power_name=power_name,
|
||||
current_phase_name=year_phase
|
||||
)
|
||||
messages_this_round_text = game_history.get_messages_this_round(power_name=power_name, current_phase_name=year_phase)
|
||||
if not messages_this_round_text.strip():
|
||||
messages_this_round_text = "\n(No messages this round)\n"
|
||||
else:
|
||||
|
|
@ -100,7 +95,7 @@ def build_context_prompt(
|
|||
# Separate active and eliminated powers for clarity
|
||||
active_powers = [p for p in game.powers.keys() if not game.powers[p].is_eliminated()]
|
||||
eliminated_powers = [p for p in game.powers.keys() if game.powers[p].is_eliminated()]
|
||||
|
||||
|
||||
# Build units representation with power status
|
||||
units_lines = []
|
||||
for p, u in board_state["units"].items():
|
||||
|
|
@ -111,7 +106,7 @@ def build_context_prompt(
|
|||
units_lines.append(f" {p}: {u_str}")
|
||||
units_repr = "\n".join(units_lines)
|
||||
|
||||
# Build centers representation with power status
|
||||
# Build centers representation with power status
|
||||
centers_lines = []
|
||||
for p, c in board_state["centers"].items():
|
||||
c_str = ", ".join(c)
|
||||
|
|
@ -125,16 +120,16 @@ def build_context_prompt(
|
|||
home_centers_str = ", ".join(HOME_CENTERS.get(power_name.upper(), []))
|
||||
|
||||
order_history_str = game_history.get_order_history_for_prompt(
|
||||
game=game, # Pass the game object for normalization
|
||||
game=game, # Pass the game object for normalization
|
||||
power_name=power_name,
|
||||
current_phase_name=year_phase,
|
||||
num_movement_phases_to_show=1
|
||||
num_movement_phases_to_show=1,
|
||||
)
|
||||
|
||||
# Replace token only if it exists (template may not include it)
|
||||
if "{home_centers}" in context_template:
|
||||
context_template = context_template.replace("{home_centers}", home_centers_str)
|
||||
|
||||
|
||||
# Following the pattern for home_centers, use replace for safety
|
||||
if "{order_history}" in context_template:
|
||||
context_template = context_template.replace("{order_history}", order_history_str)
|
||||
|
|
@ -153,9 +148,10 @@ def build_context_prompt(
|
|||
|
||||
return context
|
||||
|
||||
|
||||
def construct_order_generation_prompt(
|
||||
system_prompt: str,
|
||||
game: Any, # diplomacy.Game object
|
||||
game: Any, # diplomacy.Game object
|
||||
board_state: dict,
|
||||
power_name: str,
|
||||
possible_orders: Dict[str, List[str]],
|
||||
|
|
@ -183,20 +179,20 @@ def construct_order_generation_prompt(
|
|||
A string containing the complete prompt for the LLM.
|
||||
"""
|
||||
# Load prompts
|
||||
_ = load_prompt("few_shot_example.txt", prompts_dir=prompts_dir) # Loaded but not used, as per original logic
|
||||
_ = load_prompt("few_shot_example.txt", prompts_dir=prompts_dir) # Loaded but not used, as per original logic
|
||||
# Pick the phase-specific instruction file (using unformatted versions)
|
||||
phase_code = board_state["phase"][-1] # 'M' (movement), 'R', or 'A' / 'B'
|
||||
phase_code = board_state["phase"][-1] # 'M' (movement), 'R', or 'A' / 'B'
|
||||
if phase_code == "M":
|
||||
instructions_file = get_prompt_path("order_instructions_movement_phase.txt")
|
||||
elif phase_code in ("A", "B"): # builds / adjustments
|
||||
elif phase_code in ("A", "B"): # builds / adjustments
|
||||
instructions_file = get_prompt_path("order_instructions_adjustment_phase.txt")
|
||||
elif phase_code == "R": # retreats
|
||||
elif phase_code == "R": # retreats
|
||||
instructions_file = get_prompt_path("order_instructions_retreat_phase.txt")
|
||||
else: # unexpected – default to movement rules
|
||||
else: # unexpected – default to movement rules
|
||||
instructions_file = get_prompt_path("order_instructions_movement_phase.txt")
|
||||
|
||||
instructions = load_prompt(instructions_file, prompts_dir=prompts_dir)
|
||||
_use_simple = os.getenv("SIMPLE_PROMPTS", "0").lower() in {"1", "true", "yes"}
|
||||
_use_simple = config.SIMPLE_PROMPTS
|
||||
|
||||
# Build the context prompt
|
||||
context = build_context_prompt(
|
||||
|
|
@ -209,18 +205,29 @@ def construct_order_generation_prompt(
|
|||
agent_relationships=agent_relationships,
|
||||
agent_private_diary=agent_private_diary_str,
|
||||
prompts_dir=prompts_dir,
|
||||
include_messages=not _use_simple, # include only when *not* simple
|
||||
include_messages=not _use_simple, # include only when *not* simple
|
||||
)
|
||||
|
||||
# Append goals at the end for focus
|
||||
goals_section = ""
|
||||
if agent_goals:
|
||||
goals_section = "\n\nYOUR STRATEGIC GOALS:\n" + "\n".join(f"- {g}" for g in agent_goals) + "\n\nKeep these goals in mind when choosing your orders."
|
||||
|
||||
goals_section = (
|
||||
"\n\nYOUR STRATEGIC GOALS:\n" + "\n".join(f"- {g}" for g in agent_goals) + "\n\nKeep these goals in mind when choosing your orders."
|
||||
)
|
||||
|
||||
final_prompt = system_prompt + "\n\n" + context + "\n\n" + instructions + goals_section
|
||||
|
||||
|
||||
# Make the power names more LLM friendly
|
||||
final_prompt = final_prompt.replace('AUSTRIA', 'Austria').replace('ENGLAND', "England").replace('FRANCE', 'France').replace('GERMANY', 'Germany').replace('ITALY', "Italy").replace('RUSSIA', 'Russia').replace('TURKEY', 'Turkey')
|
||||
final_prompt = (
|
||||
final_prompt.replace("AUSTRIA", "Austria")
|
||||
.replace("ENGLAND", "England")
|
||||
.replace("FRANCE", "France")
|
||||
.replace("GERMANY", "Germany")
|
||||
.replace("ITALY", "Italy")
|
||||
.replace("RUSSIA", "Russia")
|
||||
.replace("TURKEY", "Turkey")
|
||||
)
|
||||
logger.debug(f"Final order generation prompt preview for {power_name}: {final_prompt[:500]}...")
|
||||
|
||||
return final_prompt
|
||||
return final_prompt
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue