Initial commit

This commit is contained in:
Cole Medin
2024-06-23 15:14:49 -05:00
commit 18e585b9e0
6 changed files with 270 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

View File

@@ -0,0 +1,20 @@
# Rename this file to .env once you have filled in the below environment variables!
# Get your Open AI API Key by following these instructions -
https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key
OPENAI_API_KEY=
# See all Open AI models you can use here -
# https://platform.openai.com/docs/models
# A good default to go with here is gpt-4o
OPENAI_MODEL=
# Get your personal Asana access token through the developer console in Asana.
# Feel free to follow these instructions -
# https://developers.asana.com/docs/personal-access-token
ASANA_ACCESS_TOKEN=
# The Asana project ID is in the URL when you visit a project in the Asana UI.
# If your URL is https://app.asana.com/0/123456789/1212121212, then your
# Asana project ID is 123456789
ASANA_PROJECT_ID=

144
1-first-agent/agents.py Normal file
View File

@@ -0,0 +1,144 @@
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()

View File

@@ -0,0 +1,3 @@
asana==5.0.0
openai==1.10.0
python-dotenv==0.13.0

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Cole Medin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

80
README.md Normal file
View File

@@ -0,0 +1,80 @@
<div align="center">
<a href="https://www.youtube.com/channel/UCMwVTLZIRRUyyVrkjDpn4pA">
<img alt="AI Agents Masterclass" src="https://i.imgur.com/8Gr2pBA.png">
<h1 align="center">AI Agents Masterclass</h1>
</a>
</div>
<p align="center">
Artificial Intelligence is the #1 thing for all developers to spend their time on now.
The problem is, most developers aren't focusing on AI agents, which is the real way to unleash the full power of AI.
This is why I'm creating this AI Agents Masterclass - so I can show YOU how to use AI agents to transform
businesses and create incredibly powerful software like I've already done many times!
Click the image or link above to go to the masterclass on YouTube.
</p>
<p align="center" style="margin-top: 25px">
<a href="#what-are-ai-agents"><strong>What are AI Agents?</strong></a> ·
<a href="#how-this-repo-works"><strong>How this Repo Works</strong></a> ·
<a href="#instructions-to-follow-along"><strong>Instructions to Follow Along</strong></a>
</p>
<br/>
## What are AI Agents?
AI agents are simply Large Language Models that have been given the ability to interact with the outside world. They
can do things like draft emails, book appointments in your CRM, create tasks in your task management software, and
really anything you can dream of! I hope that everything I show here can really help you dream big
and create incredible things with AI!
AI agents can be very powerful without having to create a lot of code. That doesn't mean there isn't room though
to create more complex applications to tie together many different agents to accomplish truly incredible things!
That's where we'll be heading with this masterclass and I really look forward to it!
Below is a very basic diagram just to get an idea of what an AI agent looks like:
<div align="center" style="margin-top: 25px;margin-bottom:25px">
<img width="700" alt="Trainers Ally LangGraph graph" src="https://i.imgur.com/ChRoV8W.png">
</div>
<br/>
## How this Repo Works
Each week there will be a new video for my AI Agents Masterclass! Each video will have its own folder
in this repo, starting with [/1-first-agent/](/1-first-agent) for the first video in the masterclass
where I create our very first AI agent!
The code in each folder will be exactly what I used/created in the accompanying masterclass video.
<br/>
## Instructions to Follow Along
The below instructions assume you already have Git, Python, and Pip installed. If you do not, you can install
[Python + Pip from here](https://www.python.org/downloads/) and [Git from here](https://git-scm.com/).
To follow along with any of my videos, first clone this GitHub repository, open up a terminal,
and change your directory to the folder for the current video you are watching (example: 1st video is [/1-first-agent/](/1-first-agent)).
The below instructions work on any OS - Windows, Linux, or Mac!
You will need to use the environment variables defined in the .env.example file in the folder (example for the first video: [`1-first-agent/.env.example`](/1-first-agent/.env.example)) to set up your API keys and other configuration. Turn the .env.example file into a `.env` file, and supply the necessary environment variables.
After setting up the .env file, run the below commands to create a Python virtual environment and install the necessary Python packages to run the code from the masterclass. Creating a virtual environment is optional but recommended! Creating a virtual environment for the entire masterclass is a one time thing. Make sure to run the pip install for each video though!
```bash
python -m venv ai-agents-masterclass
On Windows: .\ai-agents-masterclass\Scripts\activate
On MacOS/Linux: source ai-agents-masterclass/bin/activate
cd 1-first-agent (or whichever folder)
pip install -r requirements.txt
```
Then, you can execute the code in the folder with:
```bash
python [script name].py
```