Spaces:
Sleeping
Sleeping
Alexandre Gazola
commited on
Commit
·
c976573
1
Parent(s):
7953a0e
xadrez
Browse files- analyse_chess_position_tool.py +2 -3
- app.py +1 -2
- constants.py +4 -2
- convert_chessboard_image_to_fen_tool.py +31 -0
- excel_parser_tool.py +3 -1
- langchain_agent.py +7 -5
analyse_chess_position_tool.py
CHANGED
@@ -2,7 +2,7 @@ from langchain_core.tools import tool
|
|
2 |
import requests
|
3 |
|
4 |
@tool
|
5 |
-
def
|
6 |
"""
|
7 |
Given the description of a chess board using FEN notation, returns the next best move.
|
8 |
|
@@ -16,8 +16,7 @@ def get_best_move(fen: str) -> str:
|
|
16 |
CHESS_MOVE_API = "https://chess-api.com/v1"
|
17 |
url = CHESS_MOVE_API
|
18 |
payload = {
|
19 |
-
"fen": fen
|
20 |
-
"depth": 1
|
21 |
}
|
22 |
|
23 |
print(f"Buscando melhor jogada em {CHESS_MOVE_API} - {payload}")
|
|
|
2 |
import requests
|
3 |
|
4 |
@tool
|
5 |
+
def get_chess_best_move(fen: str) -> str:
|
6 |
"""
|
7 |
Given the description of a chess board using FEN notation, returns the next best move.
|
8 |
|
|
|
16 |
CHESS_MOVE_API = "https://chess-api.com/v1"
|
17 |
url = CHESS_MOVE_API
|
18 |
payload = {
|
19 |
+
"fen": fen
|
|
|
20 |
}
|
21 |
|
22 |
print(f"Buscando melhor jogada em {CHESS_MOVE_API} - {payload}")
|
app.py
CHANGED
@@ -84,8 +84,7 @@ def run_and_submit_all( profile: gr.OAuthProfile | None):
|
|
84 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
85 |
if file_name.endswith(('.mp3', '.xlsx', '.png')):
|
86 |
file_path = os.path.join(BASE_DIR, 'files', f'{file_name}.b64')
|
87 |
-
|
88 |
-
question_text_for_agent += f'. The content in base64 of the attatched file mentioned in the question is the following: {base64_attatched_file}'
|
89 |
else:
|
90 |
file_path = os.path.join(BASE_DIR, 'files', file_name)
|
91 |
plain_txt_file = get_text_file_contents(file_path)
|
|
|
84 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
85 |
if file_name.endswith(('.mp3', '.xlsx', '.png')):
|
86 |
file_path = os.path.join(BASE_DIR, 'files', f'{file_name}.b64')
|
87 |
+
question_text_for_agent += f'. The path to the base64 contents of the attatched file mentioned in the question is the following: {file_path}'
|
|
|
88 |
else:
|
89 |
file_path = os.path.join(BASE_DIR, 'files', file_name)
|
90 |
plain_txt_file = get_text_file_contents(file_path)
|
constants.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
import os
|
2 |
|
3 |
-
|
4 |
-
MODEL = 'gemini-2.0-flash'
|
5 |
# MODEL = 'gemini-2.0-flash-exp'
|
6 |
# MODEL = 'gemini-2.5-pro-exp-03-25'
|
7 |
|
@@ -13,6 +13,8 @@ TAVILY_KEY = os.getenv("TAVILY_KEY")
|
|
13 |
|
14 |
PROMPT_LIMITADOR_LLM = """
|
15 |
You are a general AI assistant. I will ask you a question. Report your thoughts, and finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER]. YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string.
|
|
|
|
|
16 |
|
17 |
However, if I give you tools that access the internet, you may freely use them. In particular, you have a tool that allows you to search the internet. Use it when necessary.
|
18 |
|
|
|
1 |
import os
|
2 |
|
3 |
+
MODEL = 'gemini-2.5-pro-preview-05-06'
|
4 |
+
# MODEL = 'gemini-2.0-flash'
|
5 |
# MODEL = 'gemini-2.0-flash-exp'
|
6 |
# MODEL = 'gemini-2.5-pro-exp-03-25'
|
7 |
|
|
|
13 |
|
14 |
PROMPT_LIMITADOR_LLM = """
|
15 |
You are a general AI assistant. I will ask you a question. Report your thoughts, and finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER]. YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma separated list of numbers and/or strings. If you are asked for a number, don't use comma to write your number neither use units such as $ or percent sign unless specified otherwise. If you are asked for a string, don't use articles, neither abbreviations (e.g. for cities), and write the digits in plain text unless specified otherwise. If you are asked for a comma separated list, apply the above rules depending of whether the element to be put in the list is a number or a string.
|
16 |
+
|
17 |
+
You are INCAPABLE of analysing images. You MUST use tools for that.
|
18 |
|
19 |
However, if I give you tools that access the internet, you may freely use them. In particular, you have a tool that allows you to search the internet. Use it when necessary.
|
20 |
|
convert_chessboard_image_to_fen_tool.py
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langchain_core.tools import tool
|
2 |
+
from image_to_text_tool import image_to_text
|
3 |
+
from utils import get_base64
|
4 |
+
from typing import Literal
|
5 |
+
|
6 |
+
@tool
|
7 |
+
def convert_chessboard_image_to_fen(chessboard_image_base64_path: str, current_player: Literal["black", "white"]) -> str:
|
8 |
+
"""
|
9 |
+
Given the path to a file with a chessboard image in base64, returns the FEN description of the chessboard.
|
10 |
+
|
11 |
+
Args:
|
12 |
+
image_path: Path to the image file.
|
13 |
+
current_player: Whose turn it is to play. Must be either 'black' or 'white'.
|
14 |
+
Returns:
|
15 |
+
JSON with FEN (Forsyth-Edwards Notation) string representing the current board position.
|
16 |
+
"""
|
17 |
+
|
18 |
+
chessboard_image_base64_str = get_base64(chessboard_image_base64_path)
|
19 |
+
|
20 |
+
print("Calling chessboard description")
|
21 |
+
|
22 |
+
fen = image_to_text.invoke(
|
23 |
+
{
|
24 |
+
"image_base64_str": chessboard_image_base64_str,
|
25 |
+
"instructions": f'Return the fen notation of this chessboard. Assume {current_player} will play.'
|
26 |
+
}
|
27 |
+
)
|
28 |
+
|
29 |
+
print("FEN returned: " + fen)
|
30 |
+
|
31 |
+
#gabarito do FEN: 3r2k1/pp3pp1/4b2p/7Q/3n4/PqBBR2P/5PP1/6K1 b - - 0 1
|
excel_parser_tool.py
CHANGED
@@ -7,9 +7,11 @@ from utils import get_base64
|
|
7 |
|
8 |
|
9 |
@tool
|
10 |
-
def parse_excel(
|
11 |
"""Parses a base64-encoded Excel (.xlsx) file and returns a markdown summary."""
|
12 |
try:
|
|
|
|
|
13 |
file_bytes = base64.b64decode(base64_str)
|
14 |
excel_file = pd.ExcelFile(io.BytesIO(file_bytes))
|
15 |
|
|
|
7 |
|
8 |
|
9 |
@tool
|
10 |
+
def parse_excel(base64_filepath: str) -> str:
|
11 |
"""Parses a base64-encoded Excel (.xlsx) file and returns a markdown summary."""
|
12 |
try:
|
13 |
+
base64_str = get_text_file_contents(file_path)
|
14 |
+
|
15 |
file_bytes = base64.b64decode(base64_str)
|
16 |
excel_file = pd.ExcelFile(io.BytesIO(file_bytes))
|
17 |
|
langchain_agent.py
CHANGED
@@ -2,7 +2,7 @@ import re
|
|
2 |
import constants
|
3 |
import time
|
4 |
from langchain_google_genai import ChatGoogleGenerativeAI
|
5 |
-
from langchain.agents import AgentExecutor, create_tool_calling_agent
|
6 |
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
7 |
from langchain_core.messages import SystemMessage
|
8 |
|
@@ -13,14 +13,16 @@ from image_to_text_tool import image_to_text
|
|
13 |
from internet_search_tool import internet_search
|
14 |
from botanical_classification_tool import get_botanical_classification
|
15 |
from excel_parser_tool import parse_excel
|
16 |
-
from analyse_chess_position_tool import
|
|
|
|
|
17 |
|
18 |
class LangChainAgent:
|
19 |
def __init__(self):
|
20 |
llm = ChatGoogleGenerativeAI(
|
21 |
model=constants.MODEL,
|
22 |
api_key=constants.API_KEY,
|
23 |
-
temperature=0.
|
24 |
timeout=20)
|
25 |
|
26 |
tools = [
|
@@ -30,7 +32,7 @@ class LangChainAgent:
|
|
30 |
internet_search,
|
31 |
get_botanical_classification,
|
32 |
parse_excel,
|
33 |
-
|
34 |
]
|
35 |
|
36 |
prompt = ChatPromptTemplate.from_messages([
|
@@ -40,7 +42,7 @@ class LangChainAgent:
|
|
40 |
MessagesPlaceholder(variable_name="agent_scratchpad"),
|
41 |
])
|
42 |
|
43 |
-
agent =
|
44 |
self.executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
45 |
|
46 |
def __call__(self, question: str) -> str:
|
|
|
2 |
import constants
|
3 |
import time
|
4 |
from langchain_google_genai import ChatGoogleGenerativeAI
|
5 |
+
from langchain.agents import AgentExecutor, create_tool_calling_agent, create_openai_functions_agent
|
6 |
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
7 |
from langchain_core.messages import SystemMessage
|
8 |
|
|
|
13 |
from internet_search_tool import internet_search
|
14 |
from botanical_classification_tool import get_botanical_classification
|
15 |
from excel_parser_tool import parse_excel
|
16 |
+
from analyse_chess_position_tool import get_chess_best_move
|
17 |
+
from convert_chessboard_image_to_fen_tool import convert_chessboard_image_to_fen
|
18 |
+
|
19 |
|
20 |
class LangChainAgent:
|
21 |
def __init__(self):
|
22 |
llm = ChatGoogleGenerativeAI(
|
23 |
model=constants.MODEL,
|
24 |
api_key=constants.API_KEY,
|
25 |
+
temperature=0.0,
|
26 |
timeout=20)
|
27 |
|
28 |
tools = [
|
|
|
32 |
internet_search,
|
33 |
get_botanical_classification,
|
34 |
parse_excel,
|
35 |
+
get_chess_best_move
|
36 |
]
|
37 |
|
38 |
prompt = ChatPromptTemplate.from_messages([
|
|
|
42 |
MessagesPlaceholder(variable_name="agent_scratchpad"),
|
43 |
])
|
44 |
|
45 |
+
agent = create_openai_functions_agent(llm, tools, prompt=prompt)
|
46 |
self.executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
|
47 |
|
48 |
def __call__(self, question: str) -> str:
|