Falguni commited on
Commit
dc1d5c9
·
1 Parent(s): 92cf6c8

Add function calling from modal

Browse files
Files changed (1) hide show
  1. app.py +62 -11
app.py CHANGED
@@ -5,10 +5,29 @@ import gradio as gr
5
  from src.util.board_vis import colored_unicode_board
6
  from src.util.pgn_util import pgn_string_to_game, read_pgn
7
  from src.thinksqure_engine import ThinkSquareEngine
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
 
10
  def annotate_pgn_file(
11
- file, analysis_time_per_move: float = 0.1, style: Optional[str] = "expert"
12
  ) -> str:
13
  """Annotate a chess game from a PGN file.
14
  This function takes a PGN file and annotates the chess game using an engine.
@@ -17,6 +36,13 @@ def annotate_pgn_file(
17
  """
18
  pgn_text = read_pgn(file.name)
19
 
 
 
 
 
 
 
 
20
  annotated_game = annotate_pgn(
21
  pgn_text,
22
  analysis_time_per_move=analysis_time_per_move,
@@ -40,7 +66,7 @@ def suggest_move(fen: Optional[str] = None) -> str:
40
  if fen is None or fen == "" or fen.lower() == "none" or fen.lower() == "null":
41
  fen = None
42
 
43
- best_move_san = ThinkSquareEngine.get_best_move(fen)
44
 
45
  return best_move_san
46
 
@@ -86,9 +112,19 @@ def annotate_pgn(
86
  except ValueError:
87
  raise ValueError("Analysis time must be a number.")
88
 
89
- annotated_game = ThinkSquareEngine.annotate(
90
- game, analysis_time=analysis_time_per_move, llm_character=style
91
- )
 
 
 
 
 
 
 
 
 
 
92
 
93
  return str(annotated_game)
94
 
@@ -146,11 +182,14 @@ def play_chess(
146
  - Pass the FEN string representing the board state prior to the user's last move.
147
  - Pass a move in long algebraic notation (e.g., "e4", "Nf3", "Bb5") for engine to play the next move.
148
 
 
 
 
149
  Args:
150
  move: The move to play in long algebraic notation. If None, the engine will play a move.
151
  fen: The FEN string representing the board state prior to the user's last move. If None, the game starts from the initial position.
152
  draw_board: Whether to draw the board in ASCII/Unicode/svg format. Defaults to True.
153
- render_mode: The rendering mode for the board. Defaults to "ascii". This can be "ascii", "svg", or "unicode". LLMs should default to "ascii".
154
 
155
  Returns:
156
  The best move played by the engine, the updated board state in FEN notation, and a board representation if draw_board is True else None.
@@ -171,7 +210,7 @@ def play_chess(
171
 
172
  assert fen is not None, "FEN after move should not be None"
173
 
174
- bestmove_san = ThinkSquareEngine.get_best_move(fen)
175
  fen_after_move = ThinkSquareEngine.get_fen_after_move(bestmove_san, fen)
176
 
177
  if draw_board:
@@ -228,12 +267,24 @@ with gr.Blocks(title="ThinkSquare") as app:
228
 
229
  gr.Markdown("### Analyze and Annotate a PGN File")
230
  pgn_file = gr.File(label="Upload PGN", file_types=[".pgn"])
231
- analysis_time = gr.Textbox(
232
- label="Analysis Time per Move (seconds)", value="0.1"
 
233
  )
 
234
  style_dropdown = gr.Dropdown(
235
  label="Style",
236
- choices=["expert", "novice", "jarvis", "natural"],
 
 
 
 
 
 
 
 
 
 
237
  value="expert",
238
  )
239
 
@@ -253,7 +304,7 @@ with gr.Blocks(title="ThinkSquare") as app:
253
 
254
  analyze_btn.click(
255
  fn=annotate_pgn_file,
256
- inputs=[pgn_file, analysis_time, style_dropdown],
257
  outputs=annotated_pgn_file,
258
  )
259
 
 
5
  from src.util.board_vis import colored_unicode_board
6
  from src.util.pgn_util import pgn_string_to_game, read_pgn
7
  from src.thinksqure_engine import ThinkSquareEngine
8
+ from modal import Function
9
+ import logging
10
+
11
+ logging.basicConfig(level=logging.INFO)
12
+
13
+
14
+ def get_best_move(fen: Optional[str] = None) -> str:
15
+ try:
16
+ modal_fn = Function.from_name("ThinkSquare-Backend", "get_best_move")
17
+ best_move_san = modal_fn.remote(fen)
18
+ logging.info("Best move retrieved from Modal function.")
19
+
20
+ except Exception as e:
21
+ logging.error(f"Error getting best move from Modal: {e}")
22
+
23
+ # Fallback to local engine if Modal function fails
24
+ best_move_san = ThinkSquareEngine.get_best_move(fen)
25
+
26
+ return best_move_san
27
 
28
 
29
  def annotate_pgn_file(
30
+ file, depth_level: str = "standard", style: Optional[str] = "expert"
31
  ) -> str:
32
  """Annotate a chess game from a PGN file.
33
  This function takes a PGN file and annotates the chess game using an engine.
 
36
  """
37
  pgn_text = read_pgn(file.name)
38
 
39
+ if depth_level == "standard":
40
+ analysis_time_per_move = 0.1
41
+ elif depth_level == "deep":
42
+ analysis_time_per_move = 0.5
43
+ else:
44
+ analysis_time_per_move = 0.1
45
+
46
  annotated_game = annotate_pgn(
47
  pgn_text,
48
  analysis_time_per_move=analysis_time_per_move,
 
66
  if fen is None or fen == "" or fen.lower() == "none" or fen.lower() == "null":
67
  fen = None
68
 
69
+ best_move_san = get_best_move(fen)
70
 
71
  return best_move_san
72
 
 
112
  except ValueError:
113
  raise ValueError("Analysis time must be a number.")
114
 
115
+ # try Modal function first
116
+ try:
117
+ modal_fn = Function.from_name("ThinkSquare-Backend", "annotate")
118
+ annotated_game = modal_fn.remote(pgn_input, analysis_time_per_move, style)
119
+ logging.info("Annotated game using Modal function.")
120
+
121
+ except Exception as e:
122
+ logging.error(f"Error annotating PGN with Modal: {e}")
123
+
124
+ # Fallback to local engine if Modal function fails
125
+ annotated_game = ThinkSquareEngine.annotate(
126
+ game, analysis_time=analysis_time_per_move, llm_character=style
127
+ )
128
 
129
  return str(annotated_game)
130
 
 
182
  - Pass the FEN string representing the board state prior to the user's last move.
183
  - Pass a move in long algebraic notation (e.g., "e4", "Nf3", "Bb5") for engine to play the next move.
184
 
185
+ About rendering:
186
+ - LLMs must use ascii as render_mode unless otherwise specified by user. While rendering ascii, LLMs must use monospaced font.
187
+
188
  Args:
189
  move: The move to play in long algebraic notation. If None, the engine will play a move.
190
  fen: The FEN string representing the board state prior to the user's last move. If None, the game starts from the initial position.
191
  draw_board: Whether to draw the board in ASCII/Unicode/svg format. Defaults to True.
192
+ render_mode: The rendering mode for the board. Defaults to "ascii". This can be "ascii", "svg", or "unicode".
193
 
194
  Returns:
195
  The best move played by the engine, the updated board state in FEN notation, and a board representation if draw_board is True else None.
 
210
 
211
  assert fen is not None, "FEN after move should not be None"
212
 
213
+ bestmove_san = get_best_move(fen)
214
  fen_after_move = ThinkSquareEngine.get_fen_after_move(bestmove_san, fen)
215
 
216
  if draw_board:
 
267
 
268
  gr.Markdown("### Analyze and Annotate a PGN File")
269
  pgn_file = gr.File(label="Upload PGN", file_types=[".pgn"])
270
+
271
+ analysis_depth = gr.Radio(
272
+ label="Analysis Depth", choices=["standard", "deep"], value="standard"
273
  )
274
+
275
  style_dropdown = gr.Dropdown(
276
  label="Style",
277
+ choices=[
278
+ "expert",
279
+ "novice",
280
+ "jarvis",
281
+ "natural",
282
+ "yoda",
283
+ "oracle",
284
+ "bored guy",
285
+ "angry granny",
286
+ "Sheldon Cooper (The Big Bang Theory)",
287
+ ],
288
  value="expert",
289
  )
290
 
 
304
 
305
  analyze_btn.click(
306
  fn=annotate_pgn_file,
307
+ inputs=[pgn_file, analysis_depth, style_dropdown],
308
  outputs=annotated_pgn_file,
309
  )
310