ryomo commited on
Commit
abe8a34
Β·
1 Parent(s): 389bf98

feat: add available advice options and list functionality

Browse files
Files changed (2) hide show
  1. app.py +31 -1
  2. src/unpredictable_lord/game_state.py +59 -0
app.py CHANGED
@@ -12,8 +12,10 @@ import spaces
12
 
13
  from unpredictable_lord.chat import chat_with_llm_stream
14
  from unpredictable_lord.game_state import (
 
15
  PERSONALITY_DESCRIPTIONS,
16
  create_session,
 
17
  get_session,
18
  )
19
 
@@ -55,6 +57,7 @@ def init_game(personality: str = "cautious") -> dict:
55
  "session_id": session_id,
56
  "message": f"New game started! You are now the advisor to a {personality} lord.",
57
  "personality_description": PERSONALITY_DESCRIPTIONS[personality],
 
58
  "game_state": state.to_dict(),
59
  }
60
 
@@ -87,6 +90,24 @@ def get_game_state(session_id: str) -> dict:
87
  }
88
 
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  # Gradio UI
91
  with gr.Blocks(title="Unpredictable Lord") as demo:
92
  gr.Markdown("# Unpredictable Lord\nLord Advisor AI Simulation")
@@ -170,8 +191,9 @@ Add the following to your MCP settings configuration:
170
 
171
  | Tool | Description |
172
  |------|-------------|
173
- | `init_game` | Initialize a new game session. Returns a session_id for subsequent operations. |
174
  | `get_game_state` | Get the current game state for a session. |
 
175
 
176
  ### Usage Flow
177
 
@@ -208,6 +230,14 @@ Add the following to your MCP settings configuration:
208
  fn=get_game_state, inputs=session_id_input, outputs=state_output
209
  )
210
 
 
 
 
 
 
 
 
 
211
 
212
  if __name__ == "__main__":
213
  demo.launch(mcp_server=True)
 
12
 
13
  from unpredictable_lord.chat import chat_with_llm_stream
14
  from unpredictable_lord.game_state import (
15
+ ADVICE_DESCRIPTIONS,
16
  PERSONALITY_DESCRIPTIONS,
17
  create_session,
18
+ get_available_advice,
19
  get_session,
20
  )
21
 
 
57
  "session_id": session_id,
58
  "message": f"New game started! You are now the advisor to a {personality} lord.",
59
  "personality_description": PERSONALITY_DESCRIPTIONS[personality],
60
+ "available_advice": ADVICE_DESCRIPTIONS,
61
  "game_state": state.to_dict(),
62
  }
63
 
 
90
  }
91
 
92
 
93
+ def list_available_advice() -> dict:
94
+ """
95
+ Get all available advice options that can be given to the lord.
96
+
97
+ This MCP tool returns a list of all possible advice types that can be
98
+ used with execute_turn(). The Lord AI should interpret the user's
99
+ free-form suggestion and map it to one of these options.
100
+
101
+ Returns:
102
+ dict: Dictionary containing all available advice options with
103
+ their names, descriptions, and expected effects.
104
+ """
105
+ return {
106
+ "advice_options": get_available_advice(),
107
+ "usage": "Interpret the user's advice and select the most appropriate option from the list above.",
108
+ }
109
+
110
+
111
  # Gradio UI
112
  with gr.Blocks(title="Unpredictable Lord") as demo:
113
  gr.Markdown("# Unpredictable Lord\nLord Advisor AI Simulation")
 
191
 
192
  | Tool | Description |
193
  |------|-------------|
194
+ | `init_game` | Initialize a new game session. Returns a session_id and available advice options. |
195
  | `get_game_state` | Get the current game state for a session. |
196
+ | `list_available_advice` | Get all available advice options for execute_turn. |
197
 
198
  ### Usage Flow
199
 
 
230
  fn=get_game_state, inputs=session_id_input, outputs=state_output
231
  )
232
 
233
+ gr.Markdown("### Test: List Available Advice")
234
+ list_advice_btn = gr.Button("List Advice Options")
235
+ advice_output = gr.JSON(label="Available Advice Options")
236
+
237
+ list_advice_btn.click(
238
+ fn=list_available_advice, inputs=[], outputs=advice_output
239
+ )
240
+
241
 
242
  if __name__ == "__main__":
243
  demo.launch(mcp_server=True)
src/unpredictable_lord/game_state.py CHANGED
@@ -16,6 +16,65 @@ PERSONALITY_DESCRIPTIONS = {
16
  "populist": "A popularity-focused lord who prioritizes public approval over long-term planning.",
17
  }
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  @dataclass
21
  class GameState:
 
16
  "populist": "A popularity-focused lord who prioritizes public approval over long-term planning.",
17
  }
18
 
19
+ # Available advice options that the Lord AI can choose from
20
+ AdviceType = Literal[
21
+ "increase_tax",
22
+ "decrease_tax",
23
+ "expand_territory",
24
+ "improve_diplomacy",
25
+ "public_festival",
26
+ "build_infrastructure",
27
+ "do_nothing",
28
+ ]
29
+
30
+ ADVICE_DESCRIPTIONS: dict[str, dict[str, str]] = {
31
+ "increase_tax": {
32
+ "name": "Increase Tax",
33
+ "description": "Raise taxes to increase treasury, but decrease public satisfaction.",
34
+ "effects": "Treasury ↑, Satisfaction ↓",
35
+ },
36
+ "decrease_tax": {
37
+ "name": "Decrease Tax",
38
+ "description": "Lower taxes to improve public satisfaction, but decrease treasury.",
39
+ "effects": "Treasury ↓, Satisfaction ↑",
40
+ },
41
+ "expand_territory": {
42
+ "name": "Expand Territory",
43
+ "description": "Launch a military campaign to expand territory. Risky but rewarding.",
44
+ "effects": "Territory ↑, Treasury ↓, Royal Trust Β±, Risk involved",
45
+ },
46
+ "improve_diplomacy": {
47
+ "name": "Improve Diplomacy",
48
+ "description": "Strengthen diplomatic relations with the kingdom.",
49
+ "effects": "Royal Trust ↑, Treasury ↓",
50
+ },
51
+ "public_festival": {
52
+ "name": "Hold Public Festival",
53
+ "description": "Organize a festival to boost public morale.",
54
+ "effects": "Satisfaction ↑, Treasury ↓",
55
+ },
56
+ "build_infrastructure": {
57
+ "name": "Build Infrastructure",
58
+ "description": "Invest in infrastructure to support population growth.",
59
+ "effects": "Population ↑, Treasury ↓, Long-term Treasury ↑",
60
+ },
61
+ "do_nothing": {
62
+ "name": "Do Nothing",
63
+ "description": "Maintain the current state without any action.",
64
+ "effects": "No change (turn passes)",
65
+ },
66
+ }
67
+
68
+
69
+ def get_available_advice() -> dict[str, dict[str, str]]:
70
+ """
71
+ Get all available advice options with their descriptions.
72
+
73
+ Returns:
74
+ dict: Dictionary of advice types and their descriptions.
75
+ """
76
+ return ADVICE_DESCRIPTIONS
77
+
78
 
79
  @dataclass
80
  class GameState: