minimaxir / simpleaichat

Python package for easily interfacing with chat apps, with robust features and minimal code complexity.
MIT License
3.43k stars 224 forks source link

how to pass arguments to the tool? #80

Closed pyrotank41 closed 8 months ago

pyrotank41 commented 10 months ago

is there a way we can pass a variable to the tool? the current implementation is context_dict = selected_tool(prompt) which passes prompt directly to the tool as an input, what should be done if we want to pass a variable like user_id along with the prompt for updating the database on the backend using the tool?

minimaxir commented 9 months ago

There isn't a good way to do this currently, and is a noted weakness of ReAct flows, since models only output text so there isn't a reliable way to get other metadata. A workaround is to give a schema hint in the system prompt, then parse out the schema in the tool.

It may be possible with explicit structured data schema but the current flows don't support it.

hedleyroos commented 8 months ago

This works (variable names are specific to my use case):

class ToolWrapper:                                                                                                      
    """Simpleaichat doesn't allow us to provide extra arguments to handlers. This                                       
    wrapper makes it possible to inject more by intercepting the call method.                                           
    """                                                                                                                 

    def __init__(self, tool, user_id, interaction_id):                                                                  
        self.tool = tool                                                                                                
        self.user_id = str(user_id)                                                                                     
        self.interaction_id = interaction_id                                                                            

    @property                                                                                                           
    def __doc__(self):                                                                                                  
        return self.tool.__doc__                                                                                        

    @property                                                                                                           
    def __name__(self):                                                                                                 
        return self.tool.__name__                                                                                       

    def __call__(self, prompt):                                                                                         
        return self.tool(prompt, self.user_id, self.interaction_id)

Declare your function as def handler(question, user_id, interaction_id):.

Then do the normal call flow with ai(question, tools=[ToolWrapper(sql.handler, user.id, interaction.id)]).

pyrotank41 commented 8 months ago

Thats awesome! thanks for sharing