SergeyO7 commited on
Commit
91e0b0d
·
verified ·
1 Parent(s): d600af3

Update agent.py

Browse files
Files changed (1) hide show
  1. agent.py +135 -0
agent.py CHANGED
@@ -245,6 +245,139 @@ class ExcelReaderTool(Tool):
245
  except Exception as e:
246
  return f"Error reading Excel file: {str(e)}"
247
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
248
  class PythonCodeReaderTool(Tool):
249
  name = "read_python_code"
250
  description = "Reads a Python (.py) file and returns its content as a string."
@@ -292,6 +425,8 @@ class MagAgent:
292
  ExcelReaderTool(),
293
  VisitWebpageTool(),
294
  PythonCodeReaderTool(),
 
 
295
  # GoogleSearchTool,
296
  # ImageAnalysisTool,
297
  ],
 
245
  except Exception as e:
246
  return f"Error reading Excel file: {str(e)}"
247
 
248
+
249
+
250
+ import pytesseract
251
+
252
+ @tool
253
+ def PNG2FENTool(png_file) -> str:
254
+ """Tool for converting a PNG file containing a chess board to a FEN position string.
255
+ Args:
256
+ png_file (str): The path to the PNG file.
257
+
258
+ Returns:
259
+ str: The FEN position string representing the chess board.
260
+ """
261
+ # Raises:
262
+ # - FileNotFoundError:
263
+ # If the PNG file does not exist.
264
+ # - ValueError:
265
+ # If the PNG file cannot be processed or does not contain a valid chess board.
266
+
267
+ try:
268
+ # Open the PNG file using PIL
269
+ image = Image.open(png_file)
270
+
271
+ # Use pytesseract to extract text from the image
272
+ text = pytesseract.image_to_string(image)
273
+
274
+ # Process the extracted text to get the FEN position string
275
+ fen_position = process_text_to_fen(text)
276
+
277
+ return fen_position
278
+
279
+ except FileNotFoundError:
280
+ raise FileNotFoundError("PNG file not found.")
281
+
282
+ except Exception as e:
283
+ raise ValueError("Error processing PNG file: " + str(e))
284
+
285
+ def process_text_to_fen(text):
286
+ """
287
+ Processes the extracted text from the image to obtain the FEN position string.
288
+
289
+ Parameters:
290
+ - text: str
291
+ The extracted text from the image.
292
+
293
+ Returns:
294
+ - str:
295
+ The FEN position string representing the chess board.
296
+
297
+ Raises:
298
+ - ValueError:
299
+ If the extracted text does not contain a valid chess board.
300
+ """
301
+
302
+ # Process the text to remove any unnecessary characters or spaces
303
+ processed_text = text.strip().replace("\n", "").replace(" ", "")
304
+
305
+ # Check if the processed text matches the expected format of a FEN position string
306
+ if not validate_fen_format(processed_text):
307
+ raise ValueError("Invalid chess board.")
308
+
309
+ return processed_text
310
+
311
+ def validate_fen_format(fen_string):
312
+ """
313
+ Validates if a given string matches the format of a FEN (Forsyth–Edwards Notation) position string.
314
+
315
+ Parameters:
316
+ - fen_string: str
317
+ The string to be validated.
318
+
319
+ Returns:
320
+ - bool:
321
+ True if the string matches the FEN format, False otherwise.
322
+ """
323
+
324
+ # FEN format: 8 sections separated by '/'
325
+ sections = fen_string.split("/")
326
+ if len(sections) != 8:
327
+ return False
328
+
329
+ # Check if each section contains valid characters
330
+ for section in sections:
331
+ if not validate_section(section):
332
+ return False
333
+
334
+ return True
335
+
336
+ def validate_section(section):
337
+ """
338
+ Validates if a given section of a FEN (Forsyth–Edwards Notation) position string contains valid characters.
339
+
340
+ Parameters:
341
+ - section: str
342
+ The section to be validated.
343
+
344
+ Returns:
345
+ - bool:
346
+ True if the section contains valid characters, False otherwise.
347
+ """
348
+
349
+ # Valid characters: digits 1-8 or letters 'r', 'n', 'b', 'q', 'k', 'p', 'R', 'N', 'B', 'Q', 'K', 'P'
350
+ valid_chars = set("12345678rnbqkpRNBQKP")
351
+ return all(char in valid_chars for char in section)
352
+
353
+ import chess
354
+ import chess.engine
355
+
356
+ class ChessEngineTool(Tool):
357
+ name = "chess_engine"
358
+ description = "Analyzes a chess position (FEN) with Stockfish and returns the best move."
359
+ inputs = {
360
+ "fen": {"type": "string", "description": "FEN string of the position."},
361
+ "time_limit": {"type": "number", "description": "Time in seconds for engine analysis.", "nullable": True}
362
+ }
363
+ output_type = "string"
364
+
365
+ def forward(self, fen: str, time_limit: float = 0.1) -> str:
366
+ # figure out where the binary actually is
367
+ sf_bin = shutil.which("stockfish") or "/usr/games/stockfish"
368
+ if not sf_bin:
369
+ raise RuntimeError(
370
+ f"Cannot find stockfish on PATH or at /usr/games/stockfish. "
371
+ "Did you install it in apt.txt or via apt-get?"
372
+ )
373
+
374
+ board = chess.Board(fen)
375
+ engine = chess.engine.SimpleEngine.popen_uci(sf_bin)
376
+ result = engine.play(board, chess.engine.Limit(time=time_limit))
377
+ engine.quit()
378
+ return board.san(result.move)
379
+
380
+
381
  class PythonCodeReaderTool(Tool):
382
  name = "read_python_code"
383
  description = "Reads a Python (.py) file and returns its content as a string."
 
425
  ExcelReaderTool(),
426
  VisitWebpageTool(),
427
  PythonCodeReaderTool(),
428
+ PNG2FENTool(),
429
+ ChessEngineTool(),
430
  # GoogleSearchTool,
431
  # ImageAnalysisTool,
432
  ],