mirror of
https://github.com/coleam00/ai-agents-masterclass.git
synced 2025-11-29 08:33:16 +00:00
144 lines
4.4 KiB
Python
144 lines
4.4 KiB
Python
import asana
|
|
from asana.rest import ApiException
|
|
from openai import OpenAI
|
|
from dotenv import load_dotenv
|
|
from datetime import datetime
|
|
import json
|
|
import os
|
|
|
|
load_dotenv()
|
|
|
|
client = OpenAI()
|
|
model = os.getenv('OPENAI_MODEL', 'gpt-4o')
|
|
|
|
configuration = asana.Configuration()
|
|
configuration.access_token = os.getenv('ASANA_ACCESS_TOKEN', '')
|
|
api_client = asana.ApiClient(configuration)
|
|
|
|
tasks_api_instance = asana.TasksApi(api_client)
|
|
|
|
def create_asana_task(task_name, due_on="today"):
|
|
"""
|
|
Creates a task in Asana given the name of the task and when it is due
|
|
|
|
Example call:
|
|
|
|
create_asana_task("Test Task", "2024-06-24")
|
|
Args:
|
|
task_name (str): The name of the task in Asana
|
|
due_on (str): The date the task is due in the format YYYY-MM-DD. If not given, the current day is used
|
|
Returns:
|
|
str: The API response of adding the task to Asana or an error message if the API call threw an error
|
|
"""
|
|
if due_on == "today":
|
|
due_on = str(datetime.now().date())
|
|
|
|
task_body = {
|
|
"data": {
|
|
"name": task_name,
|
|
"due_on": due_on,
|
|
"projects": [os.getenv("ASANA_PROJECT_ID", "")]
|
|
}
|
|
}
|
|
|
|
try:
|
|
api_response = tasks_api_instance.create_task(task_body, {})
|
|
return json.dumps(api_response, indent=2)
|
|
except ApiException as e:
|
|
return f"Exception when calling TasksApi->create_task: {e}"
|
|
|
|
def get_tools():
|
|
tools = [
|
|
{
|
|
"type": "function",
|
|
"function": {
|
|
"name": "create_asana_task",
|
|
"description": "Creates a task in Asana given the name of the task and when it is due",
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"task_name": {
|
|
"type": "string",
|
|
"description": "The name of the task in Asana"
|
|
},
|
|
"due_on": {
|
|
"type": "string",
|
|
"description": "The date the task is due in the format YYYY-MM-DD. If not given, the current day is used"
|
|
},
|
|
},
|
|
"required": ["task_name"]
|
|
},
|
|
},
|
|
}
|
|
]
|
|
|
|
return tools
|
|
|
|
def prompt_ai(messages):
|
|
# First, prompt the AI with the latest user message
|
|
completion = client.chat.completions.create(
|
|
model=model,
|
|
messages=messages,
|
|
tools=get_tools()
|
|
)
|
|
|
|
response_message = completion.choices[0].message
|
|
tool_calls = response_message.tool_calls
|
|
|
|
# Second, see if the AI decided it needs to invoke a tool
|
|
if tool_calls:
|
|
# If the AI decided to invoke a tool, invoke it
|
|
available_functions = {
|
|
"create_asana_task": create_asana_task
|
|
}
|
|
|
|
# Add the tool request to the list of messages so the AI knows later it invoked the tool
|
|
messages.append(response_message)
|
|
|
|
# Next, for each tool the AI wanted to call, call it and add the tool result to the list of messages
|
|
for tool_call in tool_calls:
|
|
function_name = tool_call.function.name
|
|
function_to_call = available_functions[function_name]
|
|
function_args = json.loads(tool_call.function.arguments)
|
|
function_response = function_to_call(**function_args)
|
|
|
|
messages.append({
|
|
"tool_call_id": tool_call.id,
|
|
"role": "tool",
|
|
"name": function_name,
|
|
"content": function_response
|
|
})
|
|
|
|
# Call the AI again so it can produce a response with the result of calling the tool(s)
|
|
second_response = client.chat.completions.create(
|
|
model=model,
|
|
messages=messages,
|
|
)
|
|
|
|
return second_response.choices[0].message.content
|
|
|
|
return response_message.content
|
|
|
|
def main():
|
|
messages = [
|
|
{
|
|
"role": "system",
|
|
"content": f"You are a personal assistant who helps manage tasks in Asana. The current date is: {datetime.now().date()}"
|
|
}
|
|
]
|
|
|
|
while True:
|
|
user_input = input("Chat with AI (q to quit): ").strip()
|
|
|
|
if user_input == 'q':
|
|
break
|
|
|
|
messages.append({"role": "user", "content": user_input})
|
|
ai_response = prompt_ai(messages)
|
|
|
|
print(ai_response)
|
|
messages.append({"role": "assistant", "content": ai_response})
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |