Function calling source of functions

Hi all, im new here and tried to find the answer to my question first, so im sorry if I overlooked it but I really couldn’t find it. im also quite new to developing/coding, so I might have seen the answer but not understanding it was the answer. that being said:

I created a little project where I first created a Whatsapp version of ChatGPT, I used Flask to create the webhook on a local port and then NGrok to tunnel it for verification by Facebook. This is all working now.

My next step would be to replace the default openai agent with a custom one, that has the ability to do function calling to make appointments in my agenda, so I would have some sort of personal whatsapp PA. the function for making appointments does work, but I can’t get the assistant to use it.

My projectfolder looks something like this:
token.pickle
test.py
credentials.json
app.py
.env
services/calendar_service.py
services/pycache
services
models/openai_agent.py
models/pycache
models

my openai_agent.py file looks like this, its in dutch, I am sorry, but I don’t think its relevant for the question.

from openai import OpenAI
import os
from ..services.calendar_service import CalendarService

class OpenAIAgent:
    def __init__(self):
        self.api_key = os.getenv('OPENAI_API_KEY')
        self.client = OpenAI(api_key=self.api_key)
        self.assistant_id = self.create_assistant().id
        self.thread_id = self.create_thread().id

    def create_assistant(self):
        # Creëert een assistent met specifieke instructies en tools
        assistant = self.client.beta.assistants.create(
            name="AfspraakPlanner",
            instructions="Je bent een assistent die helpt met het plannen van afspraken. Gebruik de 'calendarService' functie om een afspraak in te plannen.",
            model="gpt-4-1106-preview",
            tools=[{
                "type": "function",
                "function": {
                    "name": "calendarService",
                    "description": "Plan een afspraak in een agenda",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "date": {"type": "string", "description": "De datum van de afspraak"},
                            "time": {"type": "string", "description": "De tijd van de afspraak"},
                            "description": {"type": "string", "description": "Beschrijving van de afspraak"}
                        },
                        "required": ["date", "time", "description"]
                    }
                }
            }]
        )
        return assistant

    def create_thread(self):
        # Creëert een thread voor de conversatie
        thread = self.client.beta.threads.create()
        return thread

    def add_message_to_thread(self, content, role="user"):
        # Voegt een bericht toe aan de thread
        message = self.client.beta.threads.messages.create(
            thread_id=self.thread_id,
            role=role,
            content=content
        )
        return message

    def run_assistant(self):
        # Start de assistent op de thread
        run = self.client.beta.threads.runs.create(
            thread_id=self.thread_id,
            assistant_id=self.assistant_id
        )
        return run

    def retrieve_run_status(self, run_id):
        # Haalt de status van een run op
        run = self.client.beta.threads.runs.retrieve(
            thread_id=self.thread_id,
            run_id=run_id
        )
        return run

    def list_messages_from_thread(self):
        # Lijst alle berichten van de thread op
        messages = self.client.beta.threads.messages.list(
            thread_id=self.thread_id
        )
        return messages

my question is: how can I point to the calendar_service.py file to let the assistant know that it can find the code for executing this function calling here?

There really is no “feel free to run whatever code you want on my system” tool method.

Consider a tool function to be a unique namespace with its own parameters.

If you have different functions located in different paths and subdirectories, it is your code that must take the basic and understandable tool specification and tool output, and match that to the appropriate code methods.

The AI gives you a tool use request with parameters

[
  {
    "role": "assistant",
    "content": "Let me use my built in calendar service to figure this out...",
    "tool_calls": [
         {
          "id": "call_feaj3n3a5igi",
          "type": "function",
          "function": {
            "name": "do_calendar_stuff",
            "arguments": "{\"datestart\": \"2024-02-11\", \"type\": \"personal\", \"search_period\": 4}"
          }
        },
    }
    ]
  }
]

It is up to you to do_calendar_stuff the right way from the code’s list of functions and give the AI what it wants, not let the AI (and thus the user) perceive backend methods.

1 Like

You should be able to find quite a few examples that ‘do the whole thing’ here on the forum. I wrote about it too:

ps je mag me ook altijd in NL mailen - goed om bij te blijven!

1 Like

I still don’t get it. So how do you call end points that requires credentials through functions? Is that even possible?

That’s certainly possible.

You would write the function specification so the AI just writes the unique parameters that are needed for invoking a request. Only the language that it needs to produce. For example, it emits “tweet_to_post_to_x” as its only argument, with value “AI functions are useful!”.

Then you construct the real API call around that, with an API key, user account, user ID, session token, the real field name, etc. as needed, using other parameters stored in your system about yourself or users.