File size: 6,001 Bytes
f6bfa8e
eccf8e4
f6bfa8e
 
 
 
 
 
 
 
 
 
 
e80aab9
f6bfa8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e514fd7
f6bfa8e
 
 
 
 
 
 
e514fd7
e80aab9
f6bfa8e
 
 
 
 
3c4371f
f6bfa8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from smolagents import CodeAgent, tool, OpenAIServerModel
import requests
import io
from PIL import Image
from constants import DEFAULT_API_URL

class BasicAgent:
    def __init__(self, OPENROUTER_API: str, OPENROUTER_MODEL: str, api_url: str):
        self.api_url = api_url
        self.model = OpenAIServerModel(
            model_id=OPENROUTER_MODEL,
            api_base="https://openrouter.ai/api/v1",
            api_key=OPENROUTER_API
        )
        self.agent = None

    def initialize_agent(self):
        self.agent = CodeAgent(
            model=self.model,
            tools=[get_file],
            add_base_tools=True,
            additional_authorized_imports=['pandas', 'io']
        )
        # self.agent.tools.pop('visit_webpage') # replacing tool
        return self.agent


    def run(self, input: tuple):
        id, question, file = input

        # check if has image
        img = None
        if file and file.split('.')[1] == 'png':
            img = [Image.open(get_file(file))]

        # make a prompt
        prompt = f"""
        You are CodeAgent assistant. The user asks you a question and you provide them with a verified and specific answer.
        As an agent you have some tools to use. You may use them on demand.
        Your normal workflow should follow the following sequence:
        1. You received the question and (in some cases) additional information as a file_id. You analize it.
        2. At the planning stage you making a sequence of steps to complete this task in planning variable
        3. At the execution stage you provide an executable python code which will be parsed and executed by the program.
            Remember to provide executable code here, without any additional characters which may crash the execution and parsing.
        4. After execution you decide whether you had a final result an you can close the task providing this result or you should continue.
            If ccontinue, review you previous planning sequence: what is done, what should be change in this plan or what we should add to it?
        EACH STEP INCLUDES BOTH PLANNING AND EXECUTIONS STAGES:
            * you provide planning in a separate variable at the beggining of your answer, variable name: planning
            * execution is the rest code where you trying to achive the planned goals.
        
        The example:
        User: What is Axelord?
        [Step 1]
        Agent: 
            Planning stage:
                planning = "
                    Okay, user want me to tell him what is Axelord. I do not have this answer in my memory so I need to find it.
                    Plan:
                    1. To search: What is Axelord.
                    2. Provide an aswer.
                "
            Execution stage:
                query = "What is Axelord?"                                 
                search_result = web_search(query)                                             
                print(search_result)
            Result:
                The pages about this topic.
            Output:
                None
        [Step 2]
        Agent:
            Planning stage:
                planning = "
                    Okay, I found some websites about that.
                    Plan:
                    1. To search: What is Axelord. - DONE.
                    2. Visit the webpage to get more inforamtion.
                    3. Provide an answer.
                "
            Execution stage:
                url = "https://en.wikipedia.org/wiki/Axelord"                           
                wikipedia_page = visit_webpage(url)                                           
                print(wikipedia_page) 
            Result:
                page html output which contains an answer.
            Output:
                FinalAnswerTool(Answer)
        
        In the example above you saw how you can use searching tools, but you also has some others.
        You complete the task step by step. You recognise when the planning stage and you can do planning, and when
        the execution stage and you MUST provide an executable python code.
        
        The user's question is:
        {question}
        
        ---
        Additional information you may use:
        file_id: {file}
        
        IMPORTANT:
            * You do not answer in plain text.
            * You only answer in python code. Every plain text you need to provide you should include in a text variable
            * You may receive both images sometimes as a context. Do not forget to use them to handle the task.
        """

        # run
        return self.agent.run(
            task = prompt,
            images = img
        )

# tools
@tool
def get_file(file_id: str) -> io.BytesIO | io.StringIO | None:
    """A tool that fetches the file's content from the server.
    Use it every time you need to get file for completing the task.
    IMPORTANT: ONLY USE IT WHEN THE FILE_ID ARGUMENT IS NOT EMPTY.
    YOU MUST ENSURE THAT FILE_ID ARGUMENT IS NOT EMPTY WHEN YOU USE IT.
    Args:
        file_id: id of a file required to fetch
    Returns:
        io.BytesIO: file emulation for .xlsx or .png files. You can use this object as a file itself. It is already converted to BytesIO.
        io.StringIO: file emulation for .py files. You can use this object as a file itself. It is already converted to StringIO.
    """
    # make request
    response = requests.get(DEFAULT_API_URL+'/files/'+file_id.split('.')[0], timeout=15)
    response.raise_for_status()

    # prepare the output
    file_format = file_id.split('.')[1]
    match file_format:
        case 'png':
            print('png uploaded')
            return io.BytesIO(response.content)
        case 'xlsx':
            print('xlsx uploaded')
            return io.BytesIO(response.content)
        case 'py':
            print('py uploaded')
            return io.StringIO(response.text)
        case _:
            return None