Isics commited on
Commit
6aef72f
·
1 Parent(s): 32844c7

fixed some shit

Browse files
Files changed (5) hide show
  1. agents/manager.py +34 -14
  2. agents/utils.py +3 -2
  3. agents/web_browser.py +3 -2
  4. app.py +46 -18
  5. pyproject.toml +3 -1
agents/manager.py CHANGED
@@ -1,14 +1,11 @@
1
- import os
2
  import re
3
 
4
- from PIL import Image
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 check_file_existence(final_answer: str) -> str | None:
26
- file_pattern = r"[\w,\s-]+\.(csv|xlsx|txt|pdf|png|jpg|json)"
27
- match = re.search(file_pattern, str(final_answer))
 
 
28
 
29
- if match:
30
- filename = match.group().strip()
31
- if not os.path.exists(filename):
32
- return f"You mentioned the file '{filename}' in your final answer, but I cannot find it in the current directory. Please, make sure you have successfully executed the code to generate the file before responding."
33
 
34
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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(model_id="qwen2.5:14b", # "deepseek-r1:14b",#
18
- api_base='http://localhost:11435/v1',
19
- api_key="ollama")
20
- #model_fast = OpenAIServerModel(model_id="qwen2.5:1.5b",
 
 
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 = """ You are a strategic Orchestrator Agent. Your primary goal is to solve tasks efficiently by leveraging your available team of managed agents.
 
 
 
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
- - Before trying to solve a step on your own, take into account the agents .
46
-
47
- CRITICAL RULES FOR DELEGATION:
48
- 1. **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.
49
- 2. **Code Execution:** Only write and execute Python code for complex reasoning, data integration, or tasks that no other agent can perform.
 
 
 
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=True)
76
- results.append({"task_id": question["task_id"],
77
- "submitted_answer": response.output})
78
 
79
- with open('results.jsonl', 'a', encoding='utf-8') as f:
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
  ]