Import source: Shayan1/Prod/nash/translate
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,57 @@
|
|||||||
|
"""Optional AI-assisted input: turn a plain-English scenario description into a game
|
||||||
|
JSON file matching nash.game.Game's schema. Never called by solver.py or
|
||||||
|
simulation.py -- only reachable via the CLI's --describe flag, and its output is
|
||||||
|
always shown to the user before anything runs on it.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from nash.game import Game
|
||||||
|
|
||||||
|
SCHEMA_INSTRUCTIONS = """Translate the following plain-English description of a \
|
||||||
|
strategic situation into a normal-form game, expressed as a JSON object with \
|
||||||
|
EXACTLY this schema:
|
||||||
|
|
||||||
|
{
|
||||||
|
"players": ["<player 1 name>", "<player 2 name>", ...],
|
||||||
|
"strategies": [["<player 1 strategy A>", "<player 1 strategy B>", ...], ...],
|
||||||
|
"payoffs": [<player 1's payoff tensor>, <player 2's payoff tensor>, ...]
|
||||||
|
}
|
||||||
|
|
||||||
|
Each player's payoff tensor is nested lists with one dimension per player, sized \
|
||||||
|
to that player's number of strategies. For 2 players with strategies of length m \
|
||||||
|
and n, payoffs[i] is an m by n grid where payoffs[i][a][b] is player i's payoff \
|
||||||
|
when player 1 picks strategy index a and player 2 picks strategy index b.
|
||||||
|
|
||||||
|
Respond with ONLY the JSON object -- no explanation, no markdown code fences.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def describe_to_json(description, model="claude-sonnet-5"):
|
||||||
|
import anthropic
|
||||||
|
|
||||||
|
client = anthropic.Anthropic()
|
||||||
|
prompt = f"{SCHEMA_INSTRUCTIONS}\nDescription: {description}\n"
|
||||||
|
response = client.messages.create(
|
||||||
|
model=model,
|
||||||
|
max_tokens=2000,
|
||||||
|
messages=[{"role": "user", "content": prompt}],
|
||||||
|
)
|
||||||
|
text = response.content[0].text
|
||||||
|
data = _extract_json(text)
|
||||||
|
|
||||||
|
Game(data["players"], data["strategies"], data["payoffs"])
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _extract_json(text):
|
||||||
|
start = text.find("{")
|
||||||
|
end = text.rfind("}")
|
||||||
|
if start == -1 or end == -1:
|
||||||
|
raise ValueError(f"No JSON object found in model response:\n{text}")
|
||||||
|
return json.loads(text[start : end + 1])
|
||||||
|
|
||||||
|
|
||||||
|
def save_json(data, path):
|
||||||
|
with open(path, "w") as f:
|
||||||
|
json.dump(data, f, indent=2)
|
||||||
Reference in New Issue
Block a user