diff --git a/MultiDataSource-Agents-Tools/main.py b/MultiDataSource-Agents-Tools/main.py index d9bd923..0825351 100644 --- a/MultiDataSource-Agents-Tools/main.py +++ b/MultiDataSource-Agents-Tools/main.py @@ -70,8 +70,8 @@ # print(f'6. Response: {response["output"]}') #Below uses Arxiv and search in research paper -#response = agent_executor.invoke({"input": "What is the paper 1605.08386 talks about?"}, include_run_info=True) -#print(f'6. Response: {response["output"]}') +response = agent_executor.invoke({"input": "What is the paper 1605.08386 talks about?"}, include_run_info=True) +print(f'6. Response: {response["output"]}') # use streamlit app to get output and print response import streamlit as st diff --git a/agent-tool-externalApi/.env.example b/agent-tool-externalApi/.env.example new file mode 100644 index 0000000..16237b2 --- /dev/null +++ b/agent-tool-externalApi/.env.example @@ -0,0 +1 @@ +OPENAI_API_KEY=sk-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \ No newline at end of file diff --git a/agent-tool-externalApi/.gitignore b/agent-tool-externalApi/.gitignore new file mode 100644 index 0000000..88173fe --- /dev/null +++ b/agent-tool-externalApi/.gitignore @@ -0,0 +1,163 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +venv-app/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/agent-tool-externalApi/image-1.png b/agent-tool-externalApi/image-1.png new file mode 100644 index 0000000..0baa2ef Binary files /dev/null and b/agent-tool-externalApi/image-1.png differ diff --git a/agent-tool-externalApi/image.png b/agent-tool-externalApi/image.png new file mode 100644 index 0000000..63f310c Binary files /dev/null and b/agent-tool-externalApi/image.png differ diff --git a/agent-tool-externalApi/main.py b/agent-tool-externalApi/main.py new file mode 100644 index 0000000..ce4c4cc --- /dev/null +++ b/agent-tool-externalApi/main.py @@ -0,0 +1,215 @@ +#Import Agents and Tools +from langchain.agents import initialize_agent, Tool, AgentType +from langchain_community.agent_toolkits.load_tools import load_tools +from langchain_community.utilities import TextRequestsWrapper +from langchain_openai import OpenAI + +#import OpenAI API key and other required imports +import os +from dotenv import load_dotenv +from langchain.tools import BaseTool +import requests + +load_dotenv() + +#setup the LLM +llm = OpenAI(temperature=0.0) + +# Tools to be added + +def get_police_forces(): + # Fetch police force data from an API + url = "https://data.police.uk/api/forces" + response = requests.get(url) + if response.status_code == 200: + return response.json() + else: + return None + +def search_police_forces(name): + # Search for a specific police force by name + forces = get_police_forces() + matching_forces = [] + if forces: + for force in forces: + if name.lower() in force["name"].lower(): + matching_forces.append(force) + + return matching_forces + + return None + +class search_police_force(BaseTool): + name = "search_police_force" + description = "Useful for when you need to search for a specific police force by name" + + def _run(self, query:str) -> str: + # Use the search_police_force function to search for a police force + forces = search_police_forces(query) + return forces + + async def _arun(self, query:str) -> str: + # Use the search_police_force function to search for a police force + raise NotImplementedError("tool does not support async") +''' +#example usuage +force_id = "devon" +police_force_data = search_police_forces(force_id) +print(police_force_data) +''' + + +def get_police_force_id(force_id): + url=f'https://data.police.uk/api/forces/{force_id}' + response = requests.get(url) + if response.status_code == 200: + return response.json() + else: + return None + +class get_police_force_details(BaseTool): + name = "get_police_force_details" + description = "Useful for when you need to get details of a specific police force by ID" + + def _run(self, query:str) -> str: + # Use the get_police_force_details function to get details of a police force + force_details = get_police_force_id(query) + return force_details + + async def _arun(self, query:str) -> str: + # Use the get_police_force_details function to get details of a police force + raise NotImplementedError("tool does not support async") + +''' +#example usuage +force_id = "devon-and-cornwall" +police_force_data = get_police_force_id(force_id) +print(police_force_data) +''' + +def get_police_force_people(force_id): + url=f'https://data.police.uk/api/forces/{force_id}/people' + response = requests.get(url) + if response.status_code == 200: + return response.json() + else: + return None + +class get_police_force_peoples(BaseTool): + name = "get_police_force_people" + description = "Useful for when you need to get people details of a specific police force by ID" + + def _run(self, query:str) -> str: + # Use the get_police_force_people function to get details of people in a police force + force_people = get_police_force_people(query) + return force_people + + async def _arun(self, query:str) -> str: + # Use the get_police_force_people function to get details of people in a police force + raise NotImplementedError("tool does not support async") +''' +# example usage +force_id = "devon-and-cornwall" +police_force_data = get_police_force_people(force_id) +print(police_force_data) +''' + +def get_neighbourhoods(force_id): + url =f'https://data.police.uk/api/{force_id}/neighbourhoods' + cleaned_url = url.replace("'", "") + response = requests.get(cleaned_url) + neighbourhoods = response.json() + + if response.status_code == 200: + names = [neighbourhood['name'] for neighbourhood in neighbourhoods] + names_string = ', '.join(names) + return names_string + else: + return None + +class get_police_neighbourhoods(BaseTool): + name = "get_police_neighbourhoods" + description = "Useful for when you need to get a list of neighbourhoods in a specific police force by ID" + + def _run(self, query:str) -> str: + # Use the get_neighbourhoods function to get a list of neighbourhoods in a police force + neighbourhoods = get_neighbourhoods(query) + return neighbourhoods + + async def _arun(self, query:str) -> str: + # Use the get_neighbourhoods function to get a list of neighbourhoods in a police force + raise NotImplementedError("tool does not support async") + +''' +#usage +force_id = "\'devon-and-cornwall\'" +neighbourhoods = get_neighbourhoods(force_id) +print(neighbourhoods) +''' + +def locate_neighbourhood(latlong): + url=f'https://data.police.uk/api/locate-neighbourhood?q={latlong}' + response = requests.get(url) + if response.status_code == 200: + return response.json() + else: + return None + +class locate_police_neighbourhood(BaseTool): + name = "locate_police_neighbourhood" + description = "Useful for when you need to locate a specific police force neighbourhood by latitude and longitude" + + def _run(self, query:str) -> str: + # Use the locate_neighbourhood function to locate a neighbourhood in a police force + neighbourhood = locate_neighbourhood(query) + return neighbourhood + + async def _arun(self, query:str) -> str: + # Use the locate_neighbourhood function to locate a neighbourhood in a police force + raise NotImplementedError("tool does not support async") +''' +# example usage +latlong = "51.509865,-0.118092" +neighbourhood_data = locate_neighbourhood(latlong) +print(neighbourhood_data) +''' + +#Load the tools config that are needed + +tools =[ + Tool( + name="search_police_force", + func=search_police_force().run, + description="Useful for when you need to search for a specific police force by name" + ), + Tool( + name="get_police_force_details", + func=get_police_force_details().run, + description="Useful for when you need to get details of a specific police force by ID" + ), + Tool( + name="get_police_force_people", + func=get_police_force_peoples().run, + description="Useful for when you need to get people details of a specific police force by ID" + ), + Tool( + name="get_police_neighbourhoods", + func=get_police_neighbourhoods().run, + description="Useful for when you need to get a list of neighbourhoods in a specific police force by ID" + ), + Tool( + name="locate_police_neighbourhood", + func=locate_police_neighbourhood().run, + description="Useful for when you need to locate a specific police force neighbourhood by latitude and longitude" + ), +] + +tools = [search_police_force(),get_police_force_details(),get_police_neighbourhoods(), locate_police_neighbourhood()] +agent = initialize_agent( + tools, + llm, + agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, + verbose=True +) +response = agent.run("Get the contact number for latitude 50.365, longitude -4.1423 police station") +print(response) \ No newline at end of file diff --git a/agent-tool-externalApi/readme.md b/agent-tool-externalApi/readme.md new file mode 100644 index 0000000..9d7193d --- /dev/null +++ b/agent-tool-externalApi/readme.md @@ -0,0 +1,25 @@ +# Tools - Methods which call external API to get the output + +### Input Query provided +![alt text](image.png) + + +### Output generated +![alt text](image-1.png) + +# Usage +1. Input the OpenAI api key in the .env file. Rename the .env.example for the file +2. Create the virtual Environment + ```bash + python -m venv .\venv + #activate the environment + .\venv\scripts\activate + ``` +3. Install the python packages using the requirements.txt file + ```bash + pip install -r requirements.txt + ``` +4. Run the Code using + ```bash + python main.py + ``` \ No newline at end of file diff --git a/agent-tool-externalApi/requirements.txt b/agent-tool-externalApi/requirements.txt new file mode 100644 index 0000000..a228868 --- /dev/null +++ b/agent-tool-externalApi/requirements.txt @@ -0,0 +1,4 @@ +langchain +langchain_openai +langchain_community +python_dotenv \ No newline at end of file