File size: 2,857 Bytes
91ed61f
 
 
 
 
 
a4fc0e3
91ed61f
 
 
 
 
cb91cc3
66ec8a6
7194d01
66ec8a6
 
 
3a1daaa
66ec8a6
 
7794216
66ec8a6
fa54f6e
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
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. 

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.

------------------------------------------------------
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