Gabandino commited on
Commit
c919b6f
·
verified ·
1 Parent(s): a14ace8

Fix typo for final submission

Browse files
Files changed (1) hide show
  1. tools/chess_tools.py +122 -122
tools/chess_tools.py CHANGED
@@ -1,123 +1,123 @@
1
- from smolagents import Tool, tool
2
- from openai import OpenAI
3
- import shutil
4
-
5
-
6
- @tool
7
- def chess_engine_locator() -> str | None:
8
- """
9
- Get the path to the chess engine binary. Can be used with chess.engine.SimpleEngine.popen_uci function from chess.engine Python module.
10
- Returns:
11
- str: Path to the chess engine.
12
- """
13
- path = shutil.which('stockfish')
14
- return path if path else None
15
-
16
- class ImageToChessBoardFENTool(Tool):
17
- name = 'image_to_chess_board_fen'
18
- description = '''Convert a chessboard image to board part of the FEN.'''
19
- inputs = {
20
- 'image_url': {
21
- 'type': 'string',
22
- 'description': 'Public URL of the image (preferred) or base64 encoded image in data URL format',
23
- }
24
- }
25
- output_type = 'string'
26
-
27
- def __init__(self, client: OpenAI | None = None, **kwargs):
28
- self.client = client if client is not None else OpenAI()
29
- super().__init__(**kwargs)
30
-
31
- def attachment_for(self, task_id: str | None):
32
- self.task_id = task_id
33
-
34
- def forward(self, image_url: str) -> str:
35
- """
36
- Convert a chessboard image to board part of the FEN.
37
- Args:
38
- image_url (str): Public URL of the image (preferred) or base64 encoded image in data URL format.
39
- Returns:
40
- str: Board part of the FEN.
41
- """
42
- client = self.client
43
-
44
- response = client.response.create(
45
- model='gpt-4.1',
46
- input=[
47
- {
48
- 'role': 'user',
49
- 'content': [
50
- {
51
- 'type': 'input_text',
52
- 'text': 'Describe the position of the pieces on the chessboard from the image. Please, nothing else but description.',
53
- },
54
- {'type': 'input_image', 'image_url': image_url},
55
- ],
56
- },
57
- ],
58
- )
59
-
60
- response = client.responses.create(
61
- model='gpt-4.1',
62
- input=[
63
- {
64
- 'role': 'user',
65
- 'content': [
66
- {
67
- 'type': 'input_text',
68
- 'text': 'Describe the position of the pieces on the chessboard from the image. Please, nothing else but description.',
69
- },
70
- ],
71
- },
72
- ]
73
- + response.output
74
- + [
75
- {
76
- 'role': 'user',
77
- 'content': [
78
- {
79
- 'type': 'input_text',
80
- 'text': """\
81
- Write down all positions with known pieces.
82
- Use a standard one-letter code to name pieces.
83
- It is important to use the correct case for piece code. Use upper case for white and lower case for black.
84
- It is important to include information about all the mentioned positions.
85
- Describe each position in a new line.
86
- Follow format: <piece><position> (piece first, then position, no spaces)
87
- Return nothing but lines with positions.
88
- """,
89
- },
90
- ],
91
- }
92
- ],
93
- )
94
- board_pos = response.output_text
95
-
96
- pos_dict = {}
97
- for post_str in board_pos.splitlines():
98
- pos_str = pos_str.strip()
99
- if len(pos_str) != 3:
100
- continue
101
- piece = post_str[0]
102
- pos = pos_str[1:3]
103
- pos_dict[pos] = piece
104
-
105
- board_fen = ''
106
- for rank in range (8, 0, -1):
107
- empty = 0
108
- for file_c in range(ord('a'), ord('h') +1):
109
- file = chr(file_c)
110
- square = file + str(rank)
111
- if square in pos_dict:
112
- if empty > 0:
113
- board_fen += str(empty)
114
- empty = 0
115
- board_fen += pos_dict[square]
116
- else:
117
- empty += 1
118
- if empty > 0:
119
- board_fen += str(empty)
120
- if rank != 1:
121
- board_fen += '/'
122
-
123
  return board_fen
 
1
+ from smolagents import Tool, tool
2
+ from openai import OpenAI
3
+ import shutil
4
+
5
+
6
+ @tool
7
+ def chess_engine_locator() -> str | None:
8
+ """
9
+ Get the path to the chess engine binary. Can be used with chess.engine.SimpleEngine.popen_uci function from chess.engine Python module.
10
+ Returns:
11
+ str: Path to the chess engine.
12
+ """
13
+ path = shutil.which('stockfish')
14
+ return path if path else None
15
+
16
+ class ImageToChessBoardFENTool(Tool):
17
+ name = 'image_to_chess_board_fen'
18
+ description = '''Convert a chessboard image to board part of the FEN.'''
19
+ inputs = {
20
+ 'image_url': {
21
+ 'type': 'string',
22
+ 'description': 'Public URL of the image (preferred) or base64 encoded image in data URL format',
23
+ }
24
+ }
25
+ output_type = 'string'
26
+
27
+ def __init__(self, client: OpenAI | None = None, **kwargs):
28
+ self.client = client if client is not None else OpenAI()
29
+ super().__init__(**kwargs)
30
+
31
+ def attachment_for(self, task_id: str | None):
32
+ self.task_id = task_id
33
+
34
+ def forward(self, image_url: str) -> str:
35
+ """
36
+ Convert a chessboard image to board part of the FEN.
37
+ Args:
38
+ image_url (str): Public URL of the image (preferred) or base64 encoded image in data URL format.
39
+ Returns:
40
+ str: Board part of the FEN.
41
+ """
42
+ client = self.client
43
+
44
+ response = client.responses.create(
45
+ model='gpt-4.1',
46
+ input=[
47
+ {
48
+ 'role': 'user',
49
+ 'content': [
50
+ {
51
+ 'type': 'input_text',
52
+ 'text': 'Describe the position of the pieces on the chessboard from the image. Please, nothing else but description.',
53
+ },
54
+ {'type': 'input_image', 'image_url': image_url},
55
+ ],
56
+ },
57
+ ],
58
+ )
59
+
60
+ response = client.responses.create(
61
+ model='gpt-4.1',
62
+ input=[
63
+ {
64
+ 'role': 'user',
65
+ 'content': [
66
+ {
67
+ 'type': 'input_text',
68
+ 'text': 'Describe the position of the pieces on the chessboard from the image. Please, nothing else but description.',
69
+ },
70
+ ],
71
+ },
72
+ ]
73
+ + response.output
74
+ + [
75
+ {
76
+ 'role': 'user',
77
+ 'content': [
78
+ {
79
+ 'type': 'input_text',
80
+ 'text': """\
81
+ Write down all positions with known pieces.
82
+ Use a standard one-letter code to name pieces.
83
+ It is important to use the correct case for piece code. Use upper case for white and lower case for black.
84
+ It is important to include information about all the mentioned positions.
85
+ Describe each position in a new line.
86
+ Follow format: <piece><position> (piece first, then position, no spaces)
87
+ Return nothing but lines with positions.
88
+ """,
89
+ },
90
+ ],
91
+ }
92
+ ],
93
+ )
94
+ board_pos = response.output_text
95
+
96
+ pos_dict = {}
97
+ for post_str in board_pos.splitlines():
98
+ pos_str = pos_str.strip()
99
+ if len(pos_str) != 3:
100
+ continue
101
+ piece = post_str[0]
102
+ pos = pos_str[1:3]
103
+ pos_dict[pos] = piece
104
+
105
+ board_fen = ''
106
+ for rank in range (8, 0, -1):
107
+ empty = 0
108
+ for file_c in range(ord('a'), ord('h') +1):
109
+ file = chr(file_c)
110
+ square = file + str(rank)
111
+ if square in pos_dict:
112
+ if empty > 0:
113
+ board_fen += str(empty)
114
+ empty = 0
115
+ board_fen += pos_dict[square]
116
+ else:
117
+ empty += 1
118
+ if empty > 0:
119
+ board_fen += str(empty)
120
+ if rank != 1:
121
+ board_fen += '/'
122
+
123
  return board_fen