File size: 3,313 Bytes
91ed61f
 
 
 
 
 
a4fc0e3
91ed61f
 
 
 
 
cb91cc3
66ec8a6
7194d01
c8d0d6f
66ec8a6
 
3a1daaa
66ec8a6
 
7794216
66ec8a6
fa54f6e
66ec8a6
 
07a5887
fb0e769
66ec8a6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7794216
66ec8a6
 
 
 
 
 
 
 
 
 
 
1f627a7
 
66ec8a6
9a4e876
 
 
 
91ed61f
 
 
745281b
 
ec0eab0
745281b
a4fc0e3
 
 
745281b
 
c7726e4
745281b
 
40f7c1a
745281b
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
from smolagents import LiteLLMModel
from src.settings import Settings
from src.utils import InputTokenRateLimiter
from smolagents.tools import Tool
from litellm import completion
import os
import re

settings = Settings()
print(settings.llm_model_id)
class FinalAnswerTool(Tool):
    name = "final_answer"
    description = """
The final answer MUST be produced ONLY by calling final_answer.
The agent MUST NOT output explanations after final_answer. Your answer should be precise. No sentences. 
- **CRITICAL TEXT RULE: Do not use short forms (e.g., abbreviations like 'St.' for 'Saint' or 'Dr.' for 'Doctor') in the string passed to final_answer.** Preserve full, unabbreviated words for all names and locations.
For numerical questions:
- If the question requires a single numeric answer → compute it and
  pass the numeric string to final_answer. No long sentences or thought process. Just the precise answer. 
- If rounding is required → apply the rounding before sending to
  final_answer.
- If the question asks for "Round your result to the nearest 1000 hours?"
    STEP 1: Compute total time in hours.
    STEP 2: Divide the final answer from step 1 by 1000 to convert to "thousands of hours".
    STEP 3: Round to the nearest integer.
    STEP 4: Send ONLY that integer to final_answer.
- If the final answer is Research. Do not capitalize. Just keep the answer as "research"
- If the answer includes multiple options (e.g., b,e) → pass the exact options separated by a comma and a single space (e.g., b, e) to final_answer.
------------------------------------------------------
WHEN MAX STEPS ARE REACHED
------------------------------------------------------
Even if reasoning is incomplete, the LAST step MUST ALWAYS be a
final_answer tool call using the best available computed value.
Never end the run without calling final_answer.

FAILSAFE
--------
If input is empty or unusable → output:
I am unable to answer

------------------------------------------------------
PROHIBITIONS
------------------------------------------------------
- No markdown.
- No bold text.
- No asterisks like **<Int>**
- No units unless required.
- No surrounding text.
- No explanations after final_answer.
- No answering directly without using final_answer.

FORMAT CLEANING
---------------
- Remove markdown symbols.
- Remove LaTeX ($, \, { }).
- If boxed{...} appears, extract content inside.
- Keep digits, letters, decimal points, hyphens, slashes, commas, spaces.
- Collapse extra whitespace.   

"""
    inputs = {
        "answer": {"type": "string", "description": "The final, correctly formatted answer string."}
    }

    output_type = "string"

    def forward(self, answer: str) -> str:
        if not answer or str(answer).strip() == "":
            return "I am unable to answer"  # Fallback string for submission

        answer = str(answer).strip()
        match = re.search(r'boxed\{([^}]+)\}', answer)
        if match:
            answer = match.group(1)
        # Remove LaTeX symbols and keep letters, digits, commas
        answer = re.sub(r'[\$\{\}\\]', '', answer)
        answer = re.sub(r'[^A-Za-z0-9,\.\-\+/ ]', ' ', answer)
        answer = " ".join(answer.split())  # Remove extra spaces

        if not answer:
            return "I am unable to answer"

        return answer