mirror of
https://github.com/coleam00/ai-agents-masterclass.git
synced 2026-01-19 21:40:32 +00:00
AI Agents Masterclass #6 - RAG AI Agent
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
__pycache__
|
||||
prep
|
||||
.env
|
||||
.env
|
||||
chroma_db
|
||||
34
6-rag-task-agent/.env.example
Normal file
34
6-rag-task-agent/.env.example
Normal file
@@ -0,0 +1,34 @@
|
||||
# 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
|
||||
# You only need this environment variable set if you set LLM_MODEL to a GPT model
|
||||
OPENAI_API_KEY=
|
||||
|
||||
# Get your Anthropic API Key in your account settings -
|
||||
# https://console.anthropic.com/settings/keys
|
||||
# You only need this environment variable set if you set LLM_MODEL to a Claude model
|
||||
ANTHROPIC_API_KEY=
|
||||
|
||||
# See all Open AI models you can use here -
|
||||
# https://platform.openai.com/docs/models
|
||||
# And all Anthropic models you can use here -
|
||||
# https://docs.anthropic.com/en/docs/about-claude/models
|
||||
# A good default to go with here is gpt-4o or claude-3-5-sonnet-20240620
|
||||
LLM_MODEL=gpt-4o
|
||||
|
||||
# The absolute or relative path to the folder that has all the files for retrieval for RAG
|
||||
# If using a relative path, the path is relative to the directoy containing this .env.example file
|
||||
DIRECTORY=meeting_notes
|
||||
|
||||
# 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 workspace ID is in the URL when you visit your Asana Admin Console (when logged in).
|
||||
# Go to the URL "https://app.asana.com/admin" and then your workspace ID
|
||||
# will appear in the URL as a slew of digits once the site loads.
|
||||
# If your URL is https://app.asana.com/admin/987654321/insights, then your
|
||||
# Asana workspace ID is 987654321
|
||||
ASANA_WORKPLACE_ID=
|
||||
BIN
6-rag-task-agent/meeting_notes/2024-07-18.pdf
Normal file
BIN
6-rag-task-agent/meeting_notes/2024-07-18.pdf
Normal file
Binary file not shown.
BIN
6-rag-task-agent/meeting_notes/2024-07-19.pdf
Normal file
BIN
6-rag-task-agent/meeting_notes/2024-07-19.pdf
Normal file
Binary file not shown.
71
6-rag-task-agent/meeting_notes/2024-07-20.txt
Normal file
71
6-rag-task-agent/meeting_notes/2024-07-20.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
Meeting Notes
|
||||
Date: July 20, 2024
|
||||
Time: 11:00 AM - 12:30 PM
|
||||
Location: Conference Room C, Gaming HQ
|
||||
|
||||
Attendees:
|
||||
|
||||
Alex Thompson (CEO)
|
||||
Maria Rodriguez (CTO)
|
||||
Jamie Lee (Lead Game Designer)
|
||||
Sam Patel (Marketing Director)
|
||||
Chris Martin (Project Manager)
|
||||
Tina Nguyen (Lead Programmer)
|
||||
Emily Carter (HR Manager)
|
||||
Michael Harris (QA Lead)
|
||||
Laura Bennett (Finance Manager)
|
||||
Agenda:
|
||||
|
||||
Financial Review and Budget Allocation
|
||||
Progress Update on Technical Issues
|
||||
Marketing Campaign for Upcoming Beta
|
||||
Team Building and Morale Boosting Initiatives
|
||||
Community Event Planning
|
||||
AOB (Any Other Business)
|
||||
1. Financial Review and Budget Allocation:
|
||||
|
||||
Laura Bennett: Presented the financial report for Q2:
|
||||
Revenue exceeded projections by 15% due to the success of "Dragon's Quest."
|
||||
Proposed budget allocation for the next quarter, prioritizing new hires, marketing campaigns, and technical upgrades.
|
||||
Discussion: Team agreed to allocate additional funds towards the marketing campaign for the "Space Rangers" beta and the development of "Cyber Warriors."
|
||||
2. Progress Update on Technical Issues:
|
||||
|
||||
Tina Nguyen: Provided an update on the technical issues:
|
||||
Memory leak problems in "Space Rangers" have been resolved.
|
||||
Server stability has improved, with a new load-balancing system implemented.
|
||||
Feedback:
|
||||
Maria Rodriguez: Suggested conducting a stress test next week to ensure server robustness before the beta release.
|
||||
Michael Harris: Confirmed that QA will schedule and oversee the stress test.
|
||||
3. Marketing Campaign for Upcoming Beta:
|
||||
|
||||
Sam Patel: Detailed the marketing campaign strategy for the "Space Rangers" beta:
|
||||
Teaser trailers and gameplay videos to be released over the next two weeks.
|
||||
Social media countdown to the beta launch, with daily posts and interactive content.
|
||||
Collaboration with influencers to generate hype and attract beta testers.
|
||||
Discussion: Team brainstormed additional promotional activities, such as a beta launch livestream and exclusive in-game rewards for beta participants.
|
||||
4. Team Building and Morale Boosting Initiatives:
|
||||
|
||||
Emily Carter: Presented proposals for boosting team morale:
|
||||
Scheduled a team-building retreat for the first week of August.
|
||||
Implementing flexible working hours starting next week.
|
||||
Organizing monthly social events to foster a positive work environment.
|
||||
Feedback:
|
||||
Alex Thompson: Emphasized the importance of maintaining a healthy work-life balance and encouraged team members to take advantage of the new initiatives.
|
||||
5. Community Event Planning:
|
||||
|
||||
Jamie Lee: Discussed plans for the community event:
|
||||
Proposed an in-game tournament with prizes for the top players.
|
||||
Suggested holding a live Q&A session with the development team to engage with the community directly.
|
||||
Sam Patel: Agreed to coordinate the event and manage logistics, with a tentative date set for mid-August.
|
||||
6. AOB (Any Other Business):
|
||||
|
||||
Alex Thompson: Reminded everyone to submit their presentation proposals for the industry conference by the end of the month.
|
||||
Laura Bennett: Announced the approval of the budget for the new office in Berlin, with plans to start operations in September.
|
||||
Next Meeting: Scheduled for August 5, 2024.
|
||||
Action Items:
|
||||
|
||||
Laura Bennett: Finalize budget allocations and distribute funds as agreed.
|
||||
Tina Nguyen: Conduct a stress test for the "Space Rangers" servers next week and report results.
|
||||
Sam Patel: Implement the marketing campaign for the beta and coordinate the community event.
|
||||
Emily Carter: Organize the team-building retreat and implement flexible working hours policy.
|
||||
Meeting Adjourned at 12:30 PM.
|
||||
71
6-rag-task-agent/meeting_notes/2024-07-21.txt
Normal file
71
6-rag-task-agent/meeting_notes/2024-07-21.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
Meeting Notes
|
||||
Date: July 21, 2024
|
||||
Time: 10:00 AM - 11:30 AM
|
||||
Location: Conference Room D, Gaming HQ
|
||||
|
||||
Attendees:
|
||||
|
||||
Alex Thompson (CEO)
|
||||
Maria Rodriguez (CTO)
|
||||
Jamie Lee (Lead Game Designer)
|
||||
Sam Patel (Marketing Director)
|
||||
Chris Martin (Project Manager)
|
||||
Tina Nguyen (Lead Programmer)
|
||||
Emily Carter (HR Manager)
|
||||
Michael Harris (QA Lead)
|
||||
Sarah Walker (Customer Support Manager)
|
||||
Agenda:
|
||||
|
||||
Review of Previous Action Items
|
||||
Customer Support Enhancements
|
||||
Final Preparations for "Space Rangers" Beta
|
||||
"Cyber Warriors" Concept Feedback
|
||||
Recruitment Status and Onboarding Plans
|
||||
AOB (Any Other Business)
|
||||
1. Review of Previous Action Items:
|
||||
|
||||
Laura Bennett: Confirmed budget allocations are completed, with funds distributed to marketing and development.
|
||||
Tina Nguyen: Reported the stress test for "Space Rangers" servers is scheduled for the upcoming Monday.
|
||||
Sam Patel: Provided updates on the marketing campaign rollout, with teaser trailers receiving positive engagement.
|
||||
Emily Carter: Confirmed the team-building retreat is booked, and flexible working hours policy is now in effect.
|
||||
2. Customer Support Enhancements:
|
||||
|
||||
Sarah Walker: Presented the current state of customer support:
|
||||
Average response time reduced by 20%.
|
||||
Feedback from players highlighted the need for more detailed FAQ sections and video tutorials.
|
||||
Discussion:
|
||||
Maria Rodriguez: Suggested integrating a chatbot to handle common queries and free up support agents for complex issues.
|
||||
Chris Martin: Agreed to prioritize the development of a chatbot and assign a team for its implementation.
|
||||
3. Final Preparations for "Space Rangers" Beta:
|
||||
|
||||
Chris Martin: Outlined the final checklist for the beta launch:
|
||||
Ensure all beta testers receive their access codes and instructions by July 25, 2024.
|
||||
Conduct a final internal review of the game build.
|
||||
Schedule a pre-beta meeting with the QA team to address any last-minute issues.
|
||||
Michael Harris: Confirmed QA will be on standby during the beta launch to handle any critical bugs or crashes.
|
||||
4. "Cyber Warriors" Concept Feedback:
|
||||
|
||||
Jamie Lee: Shared findings from the market research for "Cyber Warriors":
|
||||
Strong interest in the game's concept, especially the unique multiplayer feature.
|
||||
Suggested conducting focus groups to gather more detailed feedback and refine the storyline.
|
||||
Feedback:
|
||||
Alex Thompson: Approved moving forward with focus groups and emphasized the need for a comprehensive development plan.
|
||||
5. Recruitment Status and Onboarding Plans:
|
||||
|
||||
Emily Carter: Updated on the recruitment process:
|
||||
Two senior developers and one UX/UI designer have accepted offers and will start next month.
|
||||
Onboarding plans include a comprehensive orientation program and assigning mentors to new hires.
|
||||
Discussion:
|
||||
Tina Nguyen: Highlighted the importance of quickly integrating new team members into ongoing projects to maintain momentum.
|
||||
6. AOB (Any Other Business):
|
||||
|
||||
Alex Thompson: Reminded the team about the upcoming industry conference and the importance of networking and learning from peers.
|
||||
Sarah Walker: Proposed monthly training sessions for the customer support team to keep them updated on game features and best practices.
|
||||
Next Meeting: Scheduled for August 6, 2024.
|
||||
Action Items:
|
||||
|
||||
Sarah Walker: Implement enhancements to the customer support system, including the development of a chatbot.
|
||||
Chris Martin: Finalize preparations for the "Space Rangers" beta and coordinate with the QA team.
|
||||
Jamie Lee: Organize focus groups for "Cyber Warriors" and gather detailed feedback.
|
||||
Emily Carter: Ensure smooth onboarding for new hires and facilitate their integration into projects.
|
||||
Meeting Adjourned at 11:30 AM.
|
||||
78
6-rag-task-agent/meeting_notes/2024-07-22.txt
Normal file
78
6-rag-task-agent/meeting_notes/2024-07-22.txt
Normal file
@@ -0,0 +1,78 @@
|
||||
Meeting Notes
|
||||
Date: July 22, 2024
|
||||
Time: 3:00 PM - 4:30 PM
|
||||
Location: Conference Room E, Gaming HQ
|
||||
|
||||
Attendees:
|
||||
|
||||
Alex Thompson (CEO)
|
||||
Maria Rodriguez (CTO)
|
||||
Jamie Lee (Lead Game Designer)
|
||||
Sam Patel (Marketing Director)
|
||||
Chris Martin (Project Manager)
|
||||
Tina Nguyen (Lead Programmer)
|
||||
Emily Carter (HR Manager)
|
||||
Michael Harris (QA Lead)
|
||||
Laura Bennett (Finance Manager)
|
||||
David King (Art Director)
|
||||
Agenda:
|
||||
|
||||
Review of Previous Action Items
|
||||
Art and Design Updates
|
||||
Server Stress Test Preparation
|
||||
Marketing Metrics and Adjustments
|
||||
Focus Group Planning for "Cyber Warriors"
|
||||
AOB (Any Other Business)
|
||||
1. Review of Previous Action Items:
|
||||
|
||||
Sarah Walker: Implementing the chatbot has begun, with an expected rollout in two weeks.
|
||||
Chris Martin: Final preparations for "Space Rangers" beta are on track, with beta access codes ready to be distributed.
|
||||
Jamie Lee: Scheduled focus groups for "Cyber Warriors" to begin next week.
|
||||
Emily Carter: Onboarding process for new hires has been finalized, with mentors assigned.
|
||||
2. Art and Design Updates:
|
||||
|
||||
David King: Presented updates on art and design:
|
||||
New character models for "Cyber Warriors" are 50% complete.
|
||||
Concept art for the "Mystic Adventures" expansion pack has been finalized and is ready for review.
|
||||
Feedback:
|
||||
Jamie Lee: Suggested incorporating more diverse character designs to appeal to a broader audience.
|
||||
Maria Rodriguez: Recommended scheduling regular review sessions to ensure art and design align with the overall vision of the games.
|
||||
3. Server Stress Test Preparation:
|
||||
|
||||
Tina Nguyen: Outlined the plan for the server stress test:
|
||||
Scheduled for Monday, July 24, 2024.
|
||||
Will simulate peak user loads to identify potential issues.
|
||||
QA team will monitor performance and log any anomalies.
|
||||
Discussion:
|
||||
Michael Harris: Confirmed QA team is prepared and ready to support the stress test.
|
||||
Alex Thompson: Emphasized the importance of ensuring server stability before the beta launch.
|
||||
4. Marketing Metrics and Adjustments:
|
||||
|
||||
Sam Patel: Shared metrics from the current marketing campaign:
|
||||
Teaser trailers for "Space Rangers" have received high engagement.
|
||||
Social media interactions have increased by 30% since the campaign launch.
|
||||
Feedback:
|
||||
Laura Bennett: Suggested reallocating part of the budget towards more targeted ads to maximize reach.
|
||||
Sam Patel: Agreed and proposed additional influencer partnerships to maintain momentum.
|
||||
5. Focus Group Planning for "Cyber Warriors":
|
||||
|
||||
Jamie Lee: Provided details on the focus groups:
|
||||
First session scheduled for July 28, 2024.
|
||||
Participants selected from a diverse demographic to gather comprehensive feedback.
|
||||
Focus will be on storyline, gameplay mechanics, and character customization.
|
||||
Discussion:
|
||||
Chris Martin: Suggested recording the sessions for detailed analysis and future reference.
|
||||
Maria Rodriguez: Recommended involving the UX/UI team to gain insights on user experience.
|
||||
6. AOB (Any Other Business):
|
||||
|
||||
Alex Thompson: Announced that the Berlin office is now fully operational, with a team ready to support European operations.
|
||||
Emily Carter: Proposed a wellness program for employees, including yoga sessions and mental health resources.
|
||||
Next Meeting: Scheduled for August 8, 2024.
|
||||
Action Items:
|
||||
|
||||
David King: Finalize character models and concept art, and schedule regular review sessions.
|
||||
Tina Nguyen: Execute the server stress test and report findings.
|
||||
Sam Patel: Adjust marketing strategy based on metrics and explore additional influencer partnerships.
|
||||
Jamie Lee: Conduct focus groups for "Cyber Warriors" and ensure UX/UI team involvement.
|
||||
Emily Carter: Implement the wellness program and promote it among employees.
|
||||
Meeting Adjourned at 4:30 PM.
|
||||
35
6-rag-task-agent/rag-document-loader.py
Normal file
35
6-rag-task-agent/rag-document-loader.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from langchain_community.embeddings.sentence_transformer import SentenceTransformerEmbeddings
|
||||
from langchain_community.document_loaders import DirectoryLoader
|
||||
from langchain_text_splitters import CharacterTextSplitter
|
||||
from langchain_chroma import Chroma
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
|
||||
load_dotenv()
|
||||
|
||||
rag_directory = os.getenv('DIRECTORY', 'meeting_notes')
|
||||
|
||||
def load_documents(directory):
|
||||
# Load the PDF or txt documents from the directory
|
||||
loader = DirectoryLoader(directory)
|
||||
documents = loader.load()
|
||||
|
||||
# Split the documents into chunks
|
||||
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
|
||||
docs = text_splitter.split_documents(documents)
|
||||
|
||||
return docs
|
||||
|
||||
def main():
|
||||
# Get the documents split into chunks
|
||||
docs = load_documents(rag_directory)
|
||||
|
||||
# Create the open-source embedding function
|
||||
embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
|
||||
|
||||
# Load the documents into Chroma and save it to the disk
|
||||
Chroma.from_documents(docs, embedding_function, persist_directory="./chroma_db")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
336
6-rag-task-agent/rag-task-agent.py
Normal file
336
6-rag-task-agent/rag-task-agent.py
Normal file
@@ -0,0 +1,336 @@
|
||||
import asana
|
||||
from asana.rest import ApiException
|
||||
from openai import OpenAI
|
||||
from dotenv import load_dotenv
|
||||
from datetime import datetime
|
||||
import streamlit as st
|
||||
import json
|
||||
import os
|
||||
|
||||
from langchain_core.tools import tool
|
||||
from langchain_openai import ChatOpenAI
|
||||
from langchain_anthropic import ChatAnthropic
|
||||
from langchain_core.messages import SystemMessage, AIMessage, HumanMessage, ToolMessage
|
||||
from langchain_community.embeddings.sentence_transformer import SentenceTransformerEmbeddings
|
||||
from langchain_community.document_loaders import DirectoryLoader
|
||||
from langchain_text_splitters import CharacterTextSplitter
|
||||
from langchain_chroma import Chroma
|
||||
|
||||
load_dotenv()
|
||||
|
||||
model = os.getenv('LLM_MODEL', 'gpt-4o')
|
||||
rag_directory = os.getenv('DIRECTORY', 'meeting_notes')
|
||||
|
||||
configuration = asana.Configuration()
|
||||
configuration.access_token = os.getenv('ASANA_ACCESS_TOKEN', '')
|
||||
api_client = asana.ApiClient(configuration)
|
||||
|
||||
# create an instance of the different Asana API classes
|
||||
projects_api_instance = asana.ProjectsApi(api_client)
|
||||
tasks_api_instance = asana.TasksApi(api_client)
|
||||
|
||||
workspace_gid = os.getenv("ASANA_WORKPLACE_ID", "")
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~ Function to get the Vector DB for RAG ~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@st.cache_resource
|
||||
def get_chroma_instance():
|
||||
# Create the open-source embedding function
|
||||
embedding_function = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")
|
||||
|
||||
# Get the Chroma instance from what is saved to the disk
|
||||
return Chroma(persist_directory="./chroma_db", embedding_function=embedding_function)
|
||||
|
||||
db = get_chroma_instance()
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~ AI Agent Tool Functions ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@tool
|
||||
def create_asana_task(task_name, project_gid, 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
|
||||
project_gid (str): The ID of the project to add the task to
|
||||
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": [project_gid]
|
||||
}
|
||||
}
|
||||
|
||||
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}"
|
||||
|
||||
@tool
|
||||
def get_asana_projects():
|
||||
"""
|
||||
Gets all of the projects in the user's Asana workspace
|
||||
|
||||
Returns:
|
||||
str: The API response from getting the projects or an error message if the projects couldn't be fetched.
|
||||
The API response is an array of project objects, where each project object looks like:
|
||||
{'gid': '1207789085525921', 'name': 'Project Name', 'resource_type': 'project'}
|
||||
"""
|
||||
opts = {
|
||||
'limit': 50, # int | Results per page. The number of objects to return per page. The value must be between 1 and 100.
|
||||
'workspace': workspace_gid, # str | The workspace or organization to filter projects on.
|
||||
'archived': False # bool | Only return projects whose `archived` field takes on the value of this parameter.
|
||||
}
|
||||
|
||||
try:
|
||||
api_response = projects_api_instance.get_projects(opts)
|
||||
return json.dumps(list(api_response), indent=2)
|
||||
except ApiException as e:
|
||||
return "Exception when calling ProjectsApi->create_project: %s\n" % e
|
||||
|
||||
@tool
|
||||
def create_asana_project(project_name, due_on=None):
|
||||
"""
|
||||
Creates a project in Asana given the name of the project and optionally when it is due
|
||||
|
||||
Example call:
|
||||
|
||||
create_asana_project("Test Project", "2024-06-24")
|
||||
Args:
|
||||
project_name (str): The name of the project in Asana
|
||||
due_on (str): The date the project is due in the format YYYY-MM-DD. If not supplied, the project is not given a due date
|
||||
Returns:
|
||||
str: The API response of adding the project to Asana or an error message if the API call threw an error
|
||||
"""
|
||||
body = {
|
||||
"data": {
|
||||
"name": project_name, "due_on": due_on, "workspace": workspace_gid
|
||||
}
|
||||
} # dict | The project to create.
|
||||
|
||||
try:
|
||||
# Create a project
|
||||
api_response = projects_api_instance.create_project(body, {})
|
||||
return json.dumps(api_response, indent=2)
|
||||
except ApiException as e:
|
||||
return "Exception when calling ProjectsApi->create_project: %s\n" % e
|
||||
|
||||
@tool
|
||||
def get_asana_tasks(project_gid):
|
||||
"""
|
||||
Gets all the Asana tasks in a project
|
||||
|
||||
Example call:
|
||||
|
||||
get_asana_tasks("1207789085525921")
|
||||
Args:
|
||||
project_gid (str): The ID of the project in Asana to fetch the tasks for
|
||||
Returns:
|
||||
str: The API response from fetching the tasks for the project in Asana or an error message if the API call threw an error
|
||||
The API response is an array of tasks objects where each task object is in the format:
|
||||
{'gid': '1207780961742158', 'created_at': '2024-07-11T16:25:46.380Z', 'due_on': None or date in format "YYYY-MM-DD", 'name': 'Test Task'}
|
||||
"""
|
||||
opts = {
|
||||
'limit': 50, # int | Results per page. The number of objects to return per page. The value must be between 1 and 100.
|
||||
'project': project_gid, # str | The project to filter tasks on.
|
||||
'opt_fields': "created_at,name,due_on", # list[str] | This endpoint returns a compact resource, which excludes some properties by default. To include those optional properties, set this query parameter to a comma-separated list of the properties you wish to include.
|
||||
}
|
||||
|
||||
try:
|
||||
# Get multiple tasks
|
||||
api_response = tasks_api_instance.get_tasks(opts)
|
||||
return json.dumps(list(api_response), indent=2)
|
||||
except ApiException as e:
|
||||
return "Exception when calling TasksApi->get_tasks: %s\n" % e
|
||||
|
||||
@tool
|
||||
def update_asana_task(task_gid, data):
|
||||
"""
|
||||
Updates a task in Asana by updating one or both of completed and/or the due date
|
||||
|
||||
Example call:
|
||||
|
||||
update_asana_task("1207780961742158", {"completed": True, "due_on": "2024-07-13"})
|
||||
Args:
|
||||
task_gid (str): The ID of the task to update
|
||||
data (dict): A dictionary with either one or both of the keys 'completed' and/or 'due_on'
|
||||
If given, completed needs to be either True or False.
|
||||
If given, the due date needs to be in the format 'YYYY-MM-DD'.
|
||||
Returns:
|
||||
str: The API response of updating the task or an error message if the API call threw an error
|
||||
"""
|
||||
# Data: {"completed": True or False, "due_on": "YYYY-MM-DD"}
|
||||
body = {"data": data} # dict | The task to update.
|
||||
|
||||
try:
|
||||
# Update a task
|
||||
api_response = tasks_api_instance.update_task(body, task_gid, {})
|
||||
return json.dumps(api_response, indent=2)
|
||||
except ApiException as e:
|
||||
return "Exception when calling TasksApi->update_task: %s\n" % e
|
||||
|
||||
@tool
|
||||
def delete_task(task_gid):
|
||||
"""
|
||||
Deletes a task in Asana
|
||||
|
||||
Example call:
|
||||
|
||||
delete_task("1207780961742158")
|
||||
Args:
|
||||
task_gid (str): The ID of the task to delete
|
||||
Returns:
|
||||
str: The API response of deleting the task or an error message if the API call threw an error
|
||||
"""
|
||||
try:
|
||||
# Delete a task
|
||||
api_response = tasks_api_instance.delete_task(task_gid)
|
||||
return json.dumps(api_response, indent=2)
|
||||
except ApiException as e:
|
||||
return "Exception when calling TasksApi->delete_task: %s\n" % e
|
||||
|
||||
@tool
|
||||
def query_documents(question):
|
||||
"""
|
||||
Uses RAG to query documents for information to answer a question
|
||||
that requires specific context that could be found in documents
|
||||
|
||||
Example call:
|
||||
|
||||
query_documents("What are the action items from the meeting on the 20th?")
|
||||
Args:
|
||||
question (str): The question the user asked that might be answerable from the searchable documents
|
||||
Returns:
|
||||
str: The list of texts (and their sources) that matched with the question the closest using RAG
|
||||
"""
|
||||
similar_docs = db.similarity_search(question, k=3)
|
||||
docs_formatted = list(map(lambda doc: f"Source: {doc.metadata.get('source', 'NA')}\nContent: {doc.page_content}", similar_docs))
|
||||
|
||||
return str(docs_formatted)
|
||||
|
||||
# Maps the function names to the actual function object in the script
|
||||
# This mapping will also be used to create the list of tools to bind to the agent
|
||||
available_functions = {
|
||||
"create_asana_task": create_asana_task,
|
||||
"get_asana_projects": get_asana_projects,
|
||||
"create_asana_project": create_asana_project,
|
||||
"get_asana_tasks": get_asana_tasks,
|
||||
"update_asana_task": update_asana_task,
|
||||
"delete_task": delete_task,
|
||||
"query_documents": query_documents
|
||||
}
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~ AI Prompting Function ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
def prompt_ai(messages, nested_calls=0):
|
||||
if nested_calls > 5:
|
||||
raise "AI is tool calling too much!"
|
||||
|
||||
# First, prompt the AI with the latest user message
|
||||
tools = [tool for _, tool in available_functions.items()]
|
||||
asana_chatbot = ChatOpenAI(model=model) if "gpt" in model.lower() else ChatAnthropic(model=model)
|
||||
asana_chatbot_with_tools = asana_chatbot.bind_tools(tools)
|
||||
|
||||
stream = asana_chatbot_with_tools.stream(messages)
|
||||
first = True
|
||||
for chunk in stream:
|
||||
if first:
|
||||
gathered = chunk
|
||||
first = False
|
||||
else:
|
||||
gathered = gathered + chunk
|
||||
|
||||
yield chunk
|
||||
|
||||
has_tool_calls = len(gathered.tool_calls) > 0
|
||||
|
||||
# Second, see if the AI decided it needs to invoke a tool
|
||||
if has_tool_calls:
|
||||
# Add the tool request to the list of messages so the AI knows later it invoked the tool
|
||||
messages.append(gathered)
|
||||
|
||||
# If the AI decided to invoke a tool, invoke it
|
||||
# For each tool the AI wanted to call, call it and add the tool result to the list of messages
|
||||
for tool_call in gathered.tool_calls:
|
||||
tool_name = tool_call["name"].lower()
|
||||
selected_tool = available_functions[tool_name]
|
||||
tool_output = selected_tool.invoke(tool_call["args"])
|
||||
messages.append(ToolMessage(tool_output, tool_call_id=tool_call["id"]))
|
||||
|
||||
# Call the AI again so it can produce a response with the result of calling the tool(s)
|
||||
additional_stream = prompt_ai(messages, nested_calls + 1)
|
||||
for additional_chunk in additional_stream:
|
||||
yield additional_chunk
|
||||
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~ Main Function with UI Creation ~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
system_message = f"""
|
||||
You are a personal assistant who helps manage tasks in Asana.
|
||||
You never give IDs to the user since those are just for you to keep track of.
|
||||
When a user asks to create a task and you don't know the project to add it to for sure, clarify with the user.
|
||||
The current date is: {datetime.now().date()}
|
||||
"""
|
||||
|
||||
def main():
|
||||
st.title("Asana Chatbot")
|
||||
|
||||
# Initialize chat history
|
||||
if "messages" not in st.session_state:
|
||||
st.session_state.messages = [
|
||||
SystemMessage(content=system_message)
|
||||
]
|
||||
|
||||
# Display chat messages from history on app rerun
|
||||
for message in st.session_state.messages:
|
||||
message_json = json.loads(message.json())
|
||||
message_type = message_json["type"]
|
||||
if message_type in ["human", "ai", "system"]:
|
||||
with st.chat_message(message_type):
|
||||
st.markdown(message_json["content"])
|
||||
|
||||
# React to user input
|
||||
if prompt := st.chat_input("What would you like to do today?"):
|
||||
# Display user message in chat message container
|
||||
st.chat_message("user").markdown(prompt)
|
||||
# Add user message to chat history
|
||||
st.session_state.messages.append(HumanMessage(content=prompt))
|
||||
|
||||
# Display assistant response in chat message container
|
||||
with st.chat_message("assistant"):
|
||||
stream = prompt_ai(st.session_state.messages)
|
||||
response = st.write_stream(stream)
|
||||
|
||||
st.session_state.messages.append(AIMessage(content=response))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
12
6-rag-task-agent/requirements.txt
Normal file
12
6-rag-task-agent/requirements.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
asana==5.0.7
|
||||
openai==1.10.0
|
||||
python-dotenv==0.13.0
|
||||
langchain==0.2.6
|
||||
langchain-anthropic==0.1.16
|
||||
langchain-community==0.2.6
|
||||
langchain-core==0.2.10
|
||||
langchain-openai==0.1.10
|
||||
langchain-chroma==0.1.2
|
||||
streamlit==1.36.0
|
||||
pdfminer.six==20240706
|
||||
ustructured[all-docs]
|
||||
Reference in New Issue
Block a user