Spaces:
Runtime error
Runtime error
fixed some shit
Browse files- agents/manager.py +34 -14
- agents/utils.py +3 -2
- agents/web_browser.py +3 -2
- app.py +46 -18
- pyproject.toml +3 -1
agents/manager.py
CHANGED
|
@@ -1,14 +1,11 @@
|
|
| 1 |
-
import os
|
| 2 |
import re
|
| 3 |
|
| 4 |
-
from
|
| 5 |
-
from smolagents import CodeAgent, OpenAIServerModel, Model
|
| 6 |
-
from smolagents.utils import encode_image_base64, make_image_url
|
| 7 |
|
| 8 |
from config import authorized_libraries
|
| 9 |
|
| 10 |
|
| 11 |
-
def check_no_refusal(final_answer: str) -> str | None:
|
| 12 |
refusal_phrases = [
|
| 13 |
"cannot answer", "unable to answer", "i don't know", "no se puede responder",
|
| 14 |
"lo siento", "no tengo acceso", "provide more information"
|
|
@@ -22,17 +19,40 @@ def check_no_refusal(final_answer: str) -> str | None:
|
|
| 22 |
return None
|
| 23 |
|
| 24 |
|
| 25 |
-
def
|
| 26 |
-
|
| 27 |
-
|
|
|
|
|
|
|
| 28 |
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
|
| 34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
|
|
|
| 36 |
|
| 37 |
def create_manager(model: Model, agents: list[CodeAgent], **kwargs) -> CodeAgent:
|
| 38 |
return CodeAgent(
|
|
@@ -41,7 +61,7 @@ def create_manager(model: Model, agents: list[CodeAgent], **kwargs) -> CodeAgent
|
|
| 41 |
add_base_tools=True,
|
| 42 |
additional_authorized_imports=authorized_libraries,
|
| 43 |
verbosity_level=2,
|
| 44 |
-
final_answer_checks=[],
|
| 45 |
max_steps=25,
|
| 46 |
**kwargs
|
| 47 |
)
|
|
|
|
|
|
|
| 1 |
import re
|
| 2 |
|
| 3 |
+
from smolagents import CodeAgent, Model
|
|
|
|
|
|
|
| 4 |
|
| 5 |
from config import authorized_libraries
|
| 6 |
|
| 7 |
|
| 8 |
+
def check_no_refusal(final_answer: str, **kwargs) -> str | None:
|
| 9 |
refusal_phrases = [
|
| 10 |
"cannot answer", "unable to answer", "i don't know", "no se puede responder",
|
| 11 |
"lo siento", "no tengo acceso", "provide more information"
|
|
|
|
| 19 |
return None
|
| 20 |
|
| 21 |
|
| 22 |
+
def validate_format_gaia(final_answer: str, **kwargs) -> str | None:
|
| 23 |
+
"""
|
| 24 |
+
Valida que la respuesta cumpla estrictamente con el formato de GAIA.
|
| 25 |
+
"""
|
| 26 |
+
ans = str(final_answer).strip()
|
| 27 |
|
| 28 |
+
# 1. REGLA DE CONCISIÓN (No frases largas)
|
| 29 |
+
# Si tiene más de 20 palabras, probablemente está explicando algo. GAIA quiere el dato crudo.
|
| 30 |
+
if len(ans.split()) > 20:
|
| 31 |
+
return f"Your answer is too long ({len(ans.split())} words). GAIA expects only a number, a short string, or a comma-separated list. Eliminate explanations."
|
| 32 |
|
| 33 |
+
# 2. REGLA DE UNIDADES (No $ ni %)
|
| 34 |
+
if "$" in ans or "%" in ans:
|
| 35 |
+
return "FORMAT VIOLATION: Do not use units such as '$' or '%'. Returns only the numeric value."
|
| 36 |
+
|
| 37 |
+
# 3. REGLA DE ARTÍCULOS (Para Strings)
|
| 38 |
+
# Comprobamos si empieza por "The ", "A " o "An " (case insensitive)
|
| 39 |
+
lower_ans = ans.lower()
|
| 40 |
+
if lower_ans.startswith(("the ", "a ", "an ")):
|
| 41 |
+
return "FORMAT VIOLATION: Do not use articles ('The', 'A', 'An') at the beginning of the response. Write only the noun or noun."
|
| 42 |
+
|
| 43 |
+
# 4. REGLA DE NÚMEROS (No usar comas como separador de miles)
|
| 44 |
+
# Buscamos el patrón específico de dígito + coma + 3 dígitos (ej: 1,000)
|
| 45 |
+
# Ojo: No bloqueamos listas (10, 20) porque hay un espacio después de la coma normalmente.
|
| 46 |
+
# Bloqueamos "1,200" pero permitimos "1.200" (decimal) o "1, 2" (lista)
|
| 47 |
+
if re.search(r'\d,\d{3}', ans):
|
| 48 |
+
return "FORMAT VIOLATION: Do not use commas to separate thousands (e.g. use '1200' instead of '1,200')."
|
| 49 |
+
|
| 50 |
+
# 5. REGLA DE DIGITOS EN TEXTO (Para Strings)
|
| 51 |
+
# La docu dice "write the digits in plain text unless specified otherwise".
|
| 52 |
+
# Esto es difícil de validar automáticamente sin saber la pregunta,
|
| 53 |
+
# pero podemos avisar si vemos mezcla rara. Por ahora lo dejamos pasar para no ser demasiado estrictos.
|
| 54 |
|
| 55 |
+
return None # Todo correcto
|
| 56 |
|
| 57 |
def create_manager(model: Model, agents: list[CodeAgent], **kwargs) -> CodeAgent:
|
| 58 |
return CodeAgent(
|
|
|
|
| 61 |
add_base_tools=True,
|
| 62 |
additional_authorized_imports=authorized_libraries,
|
| 63 |
verbosity_level=2,
|
| 64 |
+
final_answer_checks=[], # validate_format_gaia, check_no_refusal],
|
| 65 |
max_steps=25,
|
| 66 |
**kwargs
|
| 67 |
)
|
agents/utils.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
import pandas as pd
|
| 2 |
-
from smolagents import CodeAgent, Model, tool
|
| 3 |
|
| 4 |
from config import authorized_libraries
|
| 5 |
|
|
@@ -20,7 +20,8 @@ def create_utils(model: Model) -> CodeAgent:
|
|
| 20 |
return CodeAgent(
|
| 21 |
model=model,
|
| 22 |
tools=[
|
| 23 |
-
reverse_string
|
|
|
|
| 24 |
],
|
| 25 |
add_base_tools=True,
|
| 26 |
additional_authorized_imports=authorized_libraries,
|
|
|
|
| 1 |
import pandas as pd
|
| 2 |
+
from smolagents import CodeAgent, Model, tool, SpeechToTextTool
|
| 3 |
|
| 4 |
from config import authorized_libraries
|
| 5 |
|
|
|
|
| 20 |
return CodeAgent(
|
| 21 |
model=model,
|
| 22 |
tools=[
|
| 23 |
+
reverse_string,
|
| 24 |
+
SpeechToTextTool(),
|
| 25 |
],
|
| 26 |
add_base_tools=True,
|
| 27 |
additional_authorized_imports=authorized_libraries,
|
agents/web_browser.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
from smolagents import CodeAgent, VisitWebpageTool, DuckDuckGoSearchTool, Model
|
| 2 |
|
| 3 |
from config import authorized_libraries
|
| 4 |
|
|
@@ -9,11 +9,12 @@ def create_web_agent(model: Model) -> CodeAgent:
|
|
| 9 |
tools=[
|
| 10 |
DuckDuckGoSearchTool(),
|
| 11 |
VisitWebpageTool(),
|
|
|
|
| 12 |
],
|
| 13 |
add_base_tools=True,
|
| 14 |
additional_authorized_imports=authorized_libraries,
|
| 15 |
name="web_agent",
|
| 16 |
-
description="Browses the web to find information, can also look for information using the search engine DuckDuckGo",
|
| 17 |
verbosity_level=0,
|
| 18 |
max_steps=8,
|
| 19 |
)
|
|
|
|
| 1 |
+
from smolagents import CodeAgent, VisitWebpageTool, DuckDuckGoSearchTool, WikipediaSearchTool, Model
|
| 2 |
|
| 3 |
from config import authorized_libraries
|
| 4 |
|
|
|
|
| 9 |
tools=[
|
| 10 |
DuckDuckGoSearchTool(),
|
| 11 |
VisitWebpageTool(),
|
| 12 |
+
WikipediaSearchTool(),
|
| 13 |
],
|
| 14 |
add_base_tools=True,
|
| 15 |
additional_authorized_imports=authorized_libraries,
|
| 16 |
name="web_agent",
|
| 17 |
+
description="Browses the web to find information, can also look for information using the search engine DuckDuckGo, Wikipedia, etc",
|
| 18 |
verbosity_level=0,
|
| 19 |
max_steps=8,
|
| 20 |
)
|
app.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
| 1 |
import tempfile
|
| 2 |
import json
|
| 3 |
|
|
|
|
| 4 |
from tqdm import tqdm
|
| 5 |
|
| 6 |
-
from smolagents import OpenAIServerModel
|
| 7 |
|
| 8 |
from agents.file_reader import create_file_reader
|
| 9 |
from agents.manager import create_manager
|
|
@@ -12,12 +13,14 @@ from agents.utils import create_utils
|
|
| 12 |
from agents.web_browser import create_web_agent
|
| 13 |
from questions_api import QuestionsAPI
|
| 14 |
from tools.vision_tools import analyze_image
|
| 15 |
-
from config import IP_WINDOWS
|
| 16 |
|
| 17 |
-
model = OpenAIServerModel(
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
|
|
|
|
|
|
| 21 |
# api_base=f"http://{IP_WINDOWS}:11434/v1",
|
| 22 |
# api_key="ollama")
|
| 23 |
# model_light = OpenAIServerModel(model_id="phi3",
|
|
@@ -25,13 +28,17 @@ model = OpenAIServerModel(model_id="qwen2.5:14b", # "deepseek-r1:14b",#
|
|
| 25 |
# api_key="ollama")
|
| 26 |
|
| 27 |
manager_agent = create_manager(model,
|
| 28 |
-
tools=[analyze_image
|
|
|
|
| 29 |
agents=[create_file_reader(model),
|
| 30 |
create_web_agent(model),
|
| 31 |
create_utils(model),
|
| 32 |
create_mathematician(model)])
|
| 33 |
|
| 34 |
-
prompt = """
|
|
|
|
|
|
|
|
|
|
| 35 |
I will ask you a question. Report your thoughts, and finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER]
|
| 36 |
Instructions:
|
| 37 |
- Follow the following template: FINAL ANSWER: [YOUR FINAL ANSWER]
|
|
@@ -42,11 +49,14 @@ Instructions:
|
|
| 42 |
- CRITICAL: When giving the final answer, be extremely concise. If the user asks for a number, provide ONLY the number. If asked for a specific format, strictly follow it without chatting.
|
| 43 |
- IMPORTANT: Before giving the final answer or using a tool, you MUST think step by step. Break down the problem.
|
| 44 |
- If the deduction seems illogical, review it.
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
| 50 |
|
| 51 |
CODING RULES:
|
| 52 |
1. **Print to Debug:** You cannot see the value of variables unless you print them. ALWAYS print the head of a dataframe or the result of a calculation to confirm it's correct.
|
|
@@ -61,21 +71,39 @@ ALWAYS check your `managed_agents` list before acting. If a tool or agent exists
|
|
| 61 |
Extra info:
|
| 62 |
{extra_info_123blabla}
|
| 63 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
with tempfile.TemporaryDirectory() as tmpdir:
|
| 66 |
results = []
|
| 67 |
questions_api = QuestionsAPI(tmpdir)
|
| 68 |
for question in tqdm(questions_api.questions_generator(), total=len(questions_api.questions)):
|
|
|
|
|
|
|
|
|
|
| 69 |
extra_info = {}
|
| 70 |
if question["file_name"] != "":
|
| 71 |
extra_info["file_name"] = f"{tmpdir}/{question['file_name']}"
|
| 72 |
|
| 73 |
formatted_question = prompt.format(question_123blabla=question["question"],
|
| 74 |
extra_info_123blabla=extra_info)
|
| 75 |
-
response = manager_agent.run(formatted_question, max_steps=30, return_full_result=
|
| 76 |
-
|
| 77 |
-
|
| 78 |
|
| 79 |
-
|
| 80 |
-
json.dump(results[-1], f, ensure_ascii=True, indent=4)
|
| 81 |
print(questions_api.post_answers(results))
|
|
|
|
| 1 |
import tempfile
|
| 2 |
import json
|
| 3 |
|
| 4 |
+
import yaml
|
| 5 |
from tqdm import tqdm
|
| 6 |
|
| 7 |
+
from smolagents import OpenAIServerModel, PythonInterpreterTool
|
| 8 |
|
| 9 |
from agents.file_reader import create_file_reader
|
| 10 |
from agents.manager import create_manager
|
|
|
|
| 13 |
from agents.web_browser import create_web_agent
|
| 14 |
from questions_api import QuestionsAPI
|
| 15 |
from tools.vision_tools import analyze_image
|
| 16 |
+
from config import IP_WINDOWS, authorized_libraries
|
| 17 |
|
| 18 |
+
model = OpenAIServerModel(
|
| 19 |
+
model_id="qwen2.5:14b",
|
| 20 |
+
#model_id="deepseek-r1:14b", #
|
| 21 |
+
api_base='http://localhost:11435/v1',
|
| 22 |
+
api_key="ollama")
|
| 23 |
+
# model_fast = OpenAIServerModel(model_id="qwen2.5:1.5b",
|
| 24 |
# api_base=f"http://{IP_WINDOWS}:11434/v1",
|
| 25 |
# api_key="ollama")
|
| 26 |
# model_light = OpenAIServerModel(model_id="phi3",
|
|
|
|
| 28 |
# api_key="ollama")
|
| 29 |
|
| 30 |
manager_agent = create_manager(model,
|
| 31 |
+
tools=[analyze_image,
|
| 32 |
+
PythonInterpreterTool(authorized_imports=authorized_libraries)],
|
| 33 |
agents=[create_file_reader(model),
|
| 34 |
create_web_agent(model),
|
| 35 |
create_utils(model),
|
| 36 |
create_mathematician(model)])
|
| 37 |
|
| 38 |
+
prompt = """
|
| 39 |
+
You are a high-level Orchestrator Agent.
|
| 40 |
+
Your role is to PLAN and DELEGATE. You do NOT have direct access to external tools like web search or wikipedia.
|
| 41 |
+
|
| 42 |
I will ask you a question. Report your thoughts, and finish your answer with the following template: FINAL ANSWER: [YOUR FINAL ANSWER]
|
| 43 |
Instructions:
|
| 44 |
- Follow the following template: FINAL ANSWER: [YOUR FINAL ANSWER]
|
|
|
|
| 49 |
- CRITICAL: When giving the final answer, be extremely concise. If the user asks for a number, provide ONLY the number. If asked for a specific format, strictly follow it without chatting.
|
| 50 |
- IMPORTANT: Before giving the final answer or using a tool, you MUST think step by step. Break down the problem.
|
| 51 |
- If the deduction seems illogical, review it.
|
| 52 |
+
|
| 53 |
+
CRITICAL RULES:
|
| 54 |
+
1. **Delegation is Mandatory:** If you need to search the web, find a discography, or look up facts, you MUST use your managed agent named 'web_agent'.
|
| 55 |
+
2. **Forbidden Actions:** Do NOT attempt to call functions like 'wikipedia_search', 'google_search', or 'requests.get' directly. You will crash if you try.
|
| 56 |
+
3. **Syntax:** To use the web agent, you must generate a tool call for it.
|
| 57 |
+
Example: `result = web_agent(task="Find the discography of Mercedes Sosa...")`
|
| 58 |
+
4. **Team First Approach:** Before writing any Python code, you MUST evaluate if one of your managed agents (e.g., 'becario_windows', 'vision_tool') is capable of handling the task.
|
| 59 |
+
5. **Code Execution:** Only write and execute Python code for complex reasoning, data integration, or tasks that no other agent can perform.
|
| 60 |
|
| 61 |
CODING RULES:
|
| 62 |
1. **Print to Debug:** You cannot see the value of variables unless you print them. ALWAYS print the head of a dataframe or the result of a calculation to confirm it's correct.
|
|
|
|
| 71 |
Extra info:
|
| 72 |
{extra_info_123blabla}
|
| 73 |
"""
|
| 74 |
+
answers_file = "answers.yaml"
|
| 75 |
+
|
| 76 |
+
def add_answer_to_yaml(file_path: str, task_id: str, answer: str):
|
| 77 |
+
with open(file_path, 'r') as f:
|
| 78 |
+
cur_yaml = yaml.safe_load(f)
|
| 79 |
+
cur_yaml[task_id] = answer
|
| 80 |
+
|
| 81 |
+
if cur_yaml:
|
| 82 |
+
with open(file_path,'w') as yamlfile:
|
| 83 |
+
yaml.safe_dump(cur_yaml, yamlfile)
|
| 84 |
|
| 85 |
+
|
| 86 |
+
def load_yaml(file_path: str):
|
| 87 |
+
with open(file_path, 'r') as f:
|
| 88 |
+
return yaml.safe_load(f)
|
| 89 |
+
|
| 90 |
+
current_answers = load_yaml(answers_file)
|
| 91 |
with tempfile.TemporaryDirectory() as tmpdir:
|
| 92 |
results = []
|
| 93 |
questions_api = QuestionsAPI(tmpdir)
|
| 94 |
for question in tqdm(questions_api.questions_generator(), total=len(questions_api.questions)):
|
| 95 |
+
if question["task_id"] in current_answers.keys():
|
| 96 |
+
continue
|
| 97 |
+
|
| 98 |
extra_info = {}
|
| 99 |
if question["file_name"] != "":
|
| 100 |
extra_info["file_name"] = f"{tmpdir}/{question['file_name']}"
|
| 101 |
|
| 102 |
formatted_question = prompt.format(question_123blabla=question["question"],
|
| 103 |
extra_info_123blabla=extra_info)
|
| 104 |
+
response = manager_agent.run(formatted_question, max_steps=30, return_full_result=False)
|
| 105 |
+
response = str(response)
|
| 106 |
+
results.append({"task_id": question["task_id"], "submitted_answer": response})
|
| 107 |
|
| 108 |
+
add_answer_to_yaml(file_path=answers_file, task_id=question["task_id"], answer=response)
|
|
|
|
| 109 |
print(questions_api.post_answers(results))
|
pyproject.toml
CHANGED
|
@@ -12,6 +12,8 @@ dependencies = [
|
|
| 12 |
"openpyxl>=3.1.5",
|
| 13 |
"pillow>=12.0.0",
|
| 14 |
"pypdf>=6.4.0",
|
| 15 |
-
"smolagents[openai]>=1.23.0",
|
| 16 |
"sympy>=1.14.0",
|
|
|
|
|
|
|
| 17 |
]
|
|
|
|
| 12 |
"openpyxl>=3.1.5",
|
| 13 |
"pillow>=12.0.0",
|
| 14 |
"pypdf>=6.4.0",
|
| 15 |
+
"smolagents[openai,transformers]>=1.23.0",
|
| 16 |
"sympy>=1.14.0",
|
| 17 |
+
"transformers>=4.57.3",
|
| 18 |
+
"wikipedia-api>=0.8.1",
|
| 19 |
]
|