From b66ed4234c8bb0daeac5c0aea27c4228e7fb8437 Mon Sep 17 00:00:00 2001 From: Sadaf Siddiqui Date: Mon, 6 May 2024 18:03:39 +0500 Subject: [PATCH 01/11] Create pylint.yml --- .github/workflows/pylint.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/pylint.yml diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml new file mode 100644 index 0000000..c73e032 --- /dev/null +++ b/.github/workflows/pylint.yml @@ -0,0 +1,23 @@ +name: Pylint + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.8", "3.9", "3.10"] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint + - name: Analysing the code with pylint + run: | + pylint $(git ls-files '*.py') From 9213349303024c9325e94975cfefe750df48ebff Mon Sep 17 00:00:00 2001 From: Sadaf Siddiqui Date: Mon, 6 May 2024 18:08:50 +0500 Subject: [PATCH 02/11] Create vercel.json --- vercel.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 vercel.json diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..5fedaf1 --- /dev/null +++ b/vercel.json @@ -0,0 +1,15 @@ +{ + "version": 2, + "builds": [ + { + "src": "app.py", + "use": "@vercel/python" + } + ], + "routes": [ + { + "src": "/(.*)", + "dest": "app/main.py" + } + ] +} From 7a7d94657b1e0b8fd9e3a2b2db45f02e3bcd78b9 Mon Sep 17 00:00:00 2001 From: halfbug Date: Mon, 6 May 2024 20:23:10 +0500 Subject: [PATCH 03/11] config --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index 5fedaf1..7053943 100644 --- a/vercel.json +++ b/vercel.json @@ -2,7 +2,7 @@ "version": 2, "builds": [ { - "src": "app.py", + "src": "app/main.py", "use": "@vercel/python" } ], From e028f0addd20ae45a251eef50bef4410bbeeb0d6 Mon Sep 17 00:00:00 2001 From: Sadaf Siddiqui <92418104+sadafgs@users.noreply.github.com> Date: Tue, 7 May 2024 19:57:38 +0500 Subject: [PATCH 04/11] added search and basic modal (#19) Co-authored-by: halfbug --- .gitignore | 4 +- app/api/v1/llm.py | 12 ++++++ app/core/config.py | 2 +- app/utils/__init__.py | 0 app/utils/llm/__init__.py | 0 app/utils/llm/conversation_agent.py | 38 ++++++++++++++++++ app/utils/llm/openai_model.py | 25 ++++++++++++ app/utils/llm/sysprompt/__init__.py | 0 .../llm/sysprompt/conversational_agent.py | 7 ++++ app/utils/llm/tools/__init__.py | 0 .../llm/tools/{websearch.py => web_search.py} | 5 ++- requirements.txt | Bin 320 -> 460 bytes 12 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 app/utils/__init__.py create mode 100644 app/utils/llm/__init__.py create mode 100644 app/utils/llm/conversation_agent.py create mode 100644 app/utils/llm/openai_model.py create mode 100644 app/utils/llm/sysprompt/__init__.py create mode 100644 app/utils/llm/sysprompt/conversational_agent.py create mode 100644 app/utils/llm/tools/__init__.py rename app/utils/llm/tools/{websearch.py => web_search.py} (92%) diff --git a/.gitignore b/.gitignore index 42d3722..7700ec7 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,10 @@ __pycache__ Downloads # Environments -.env +.env +.sqlite3 .venv +.bin env/ venv/ ENV/ diff --git a/app/api/v1/llm.py b/app/api/v1/llm.py index e1ebc7f..48f3ce7 100644 --- a/app/api/v1/llm.py +++ b/app/api/v1/llm.py @@ -2,6 +2,10 @@ from fastapi import APIRouter, HTTPException from pydantic import BaseModel +from app.utils.llm.conversation_agent import ConversationAgent +from app.utils.llm.openai_model import OpenAIModel +from app.utils.llm.tools.web_search import search_web + router = APIRouter() @@ -20,6 +24,14 @@ class PromptResponse(BaseModel): async def prompt(request_data: PromptRequest): try: reply_message = f"You said: {request_data.message}" + + tools = [search_web] # Define your tools + workroom_modal = OpenAIModel(tools=tools) # Initialize the OpenAI model + conversation_agent = ConversationAgent(openai_model=workroom_modal, tools=tools) + + reply_message = conversation_agent.convchain(request_data.message) + print(reply_message) + # Example of creating a pandas DataFrame (replace this with your actual data) data = {"column1": [1, 2, 3], "column2": [4, 5, 6]} df = pd.DataFrame(data) diff --git a/app/core/config.py b/app/core/config.py index d268cce..65efaa3 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -59,5 +59,5 @@ def get_config(env_state: str): # print(os.path.expanduser("~/.env")) # print(GlobalConfig().DATABASE_URL) # print(BaseConfig().ENV_STATE) -# print(get_config(BaseConfig().ENV_STATE)) +# print(get_config(BaseConfig())) config = get_config(BaseConfig().ENV_STATE) diff --git a/app/utils/__init__.py b/app/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/utils/llm/__init__.py b/app/utils/llm/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/utils/llm/conversation_agent.py b/app/utils/llm/conversation_agent.py new file mode 100644 index 0000000..ddbf874 --- /dev/null +++ b/app/utils/llm/conversation_agent.py @@ -0,0 +1,38 @@ +from langchain.agents import AgentExecutor +from langchain.memory import ConversationBufferMemory +from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder + +from app.utils.llm.sysprompt.conversational_agent import CONVERSATIONAL_AGENT_PROMPT + + + +class ConversationAgent: + def __init__(self, openai_model, tools): + self.openai_model = openai_model + self.memory = ConversationBufferMemory( + return_messages=True, memory_key="chat_history" + ) + self.prompt = self.create_prompt() + self.chain = self.openai_model.create_functional_chain(self.prompt) + self.qa = AgentExecutor( + agent=self.chain, tools=tools, verbose=True, memory=self.memory + ) + + def create_prompt(self): + return ChatPromptTemplate.from_messages( + [ + ( + "system", + CONVERSATIONAL_AGENT_PROMPT, + ), + MessagesPlaceholder(variable_name="chat_history"), + ("user", "{input}"), + MessagesPlaceholder(variable_name="agent_scratchpad"), + ] + ) + + def convchain(self, query): + if not query: + return + result = self.qa.invoke({"input": query}) + return result["output"] diff --git a/app/utils/llm/openai_model.py b/app/utils/llm/openai_model.py new file mode 100644 index 0000000..3b5d118 --- /dev/null +++ b/app/utils/llm/openai_model.py @@ -0,0 +1,25 @@ +from langchain.agents.format_scratchpad import format_to_openai_functions +from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser +from langchain.chat_models import ChatOpenAI +from langchain.schema.runnable import RunnablePassthrough +from langchain.tools.render import format_tool_to_openai_function +from app.core.config import config + + +class OpenAIModel: + def __init__(self, tools): + + self.functions = [format_tool_to_openai_function(f) for f in tools] + self.chat_model = ChatOpenAI(openai_api_key=config.OPENAI_API_KEY,temperature=0).bind(functions=self.functions) + + def create_functional_chain(self, prompt): + return ( + RunnablePassthrough.assign( + agent_scratchpad=lambda x: format_to_openai_functions( + x["intermediate_steps"] + ) + ) + | prompt + | self.chat_model + | OpenAIFunctionsAgentOutputParser() + ) diff --git a/app/utils/llm/sysprompt/__init__.py b/app/utils/llm/sysprompt/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/utils/llm/sysprompt/conversational_agent.py b/app/utils/llm/sysprompt/conversational_agent.py new file mode 100644 index 0000000..837df36 --- /dev/null +++ b/app/utils/llm/sysprompt/conversational_agent.py @@ -0,0 +1,7 @@ +# sysprompt/conversational_agent.py + +CONVERSATIONAL_AGENT_PROMPT = "You are a helpful but sassy assistant. If you don't find anything, don't hallucinate it." +# CONVERSATIONAL_AGENT_PROMPT = ( +# "You are a helpful but sassy assistant. " +# "If you don't find anything, don't hallucinate it." +# ) \ No newline at end of file diff --git a/app/utils/llm/tools/__init__.py b/app/utils/llm/tools/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/utils/llm/tools/websearch.py b/app/utils/llm/tools/web_search.py similarity index 92% rename from app/utils/llm/tools/websearch.py rename to app/utils/llm/tools/web_search.py index f785811..40d3b9f 100644 --- a/app/utils/llm/tools/websearch.py +++ b/app/utils/llm/tools/web_search.py @@ -1,14 +1,17 @@ import os + from langchain.chains import RetrievalQAWithSourcesChain from langchain.retrievers.web_research import WebResearchRetriever from langchain.tools import tool from langchain_chroma import Chroma from langchain_community.utilities import GoogleSearchAPIWrapper from langchain_openai import ChatOpenAI, OpenAIEmbeddings +from bs4 import BeautifulSoup from app.core.config import config os.environ["GOOGLE_API_KEY"] = config.GOOGLE_API_KEY os.environ["GOOGLE_CSE_ID"] = config.GOOGLE_CSE_ID +os.environ["OPENAI_API_KEY"] = config.OPENAI_API_KEY @tool @@ -26,7 +29,7 @@ def search_web(query): ) # LLM - llm = ChatOpenAI(temperature=0) + llm = ChatOpenAI(openai_api_key=config.OPENAI_API_KEY, temperature=0) # Search search = GoogleSearchAPIWrapper() diff --git a/requirements.txt b/requirements.txt index 63b6c402547fceea1ba31b80960e5891cc2b3ac3..e29f047e3c483f6af53e1eeaa7d905e60084aca8 100644 GIT binary patch delta 131 zcmX@WbcT7tr-?g+gmoE`8S)u&fv}Vzk0FzxgrRcc+u)>hpkO{jIztXaDuXUVB0~XC zN*7300u^KcW%7W$WT0#&P(BYRX2)R5V8o!uV8~zqgnB^C%fQ9p1e8q#8e9TYmj Date: Wed, 8 May 2024 18:22:53 +0500 Subject: [PATCH 05/11] add sqlite --- requirements.txt | Bin 460 -> 498 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index e29f047e3c483f6af53e1eeaa7d905e60084aca8..5a98b78549246f8e00628f18b2abc4bef3923ab1 100644 GIT binary patch delta 46 xcmX@Z{E2zP8Adf;1}=tThC+rMhD?SMhExV)1_cH?23sI$%%BIvra;nw0RZ{{2qpjk delta 7 Ocmeywe1>_$8AbpOXahn3 From d97e3e659376f65361a740efff3c72043c292157 Mon Sep 17 00:00:00 2001 From: halfbug Date: Wed, 8 May 2024 18:24:23 +0500 Subject: [PATCH 06/11] readd sqlite --- requirements.txt | Bin 498 -> 480 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index 5a98b78549246f8e00628f18b2abc4bef3923ab1..8480e42fd644b9bad9b4bc43796b55de53b53c20 100644 GIT binary patch delta 7 Ocmeyw{D67G14aN2^aE-D delta 26 ecmaFB{E2zP14bb`23rON24e<2AT|Y(1`GgW4h22{ From e3f13aa7c3756b0f4164a40b9df5b55654829e41 Mon Sep 17 00:00:00 2001 From: halfbug Date: Wed, 8 May 2024 18:26:22 +0500 Subject: [PATCH 07/11] sqlite3>=3.35.0 --- requirements.txt | Bin 480 -> 494 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8480e42fd644b9bad9b4bc43796b55de53b53c20..c00a6020d09807b24d3c20ee9289c21a3165b967 100644 GIT binary patch delta 24 ccmaFB{Em6UJw^dL23rPW20b7)1(F5~09e2U761SM delta 10 RcmaFI{D67GJw_%41^^jG1BL(q From c52e7165945fe2d6d3f134483e51c9d9afc7b59f Mon Sep 17 00:00:00 2001 From: halfbug Date: Wed, 8 May 2024 18:32:11 +0500 Subject: [PATCH 08/11] removed sqlite3>=3.35.0 --- requirements.txt | Bin 494 -> 464 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index c00a6020d09807b24d3c20ee9289c21a3165b967..5f5387e234bfc7ff0594c4c495948e656e48e7e1 100644 GIT binary patch delta 7 OcmaFIe1Unx1x5f4Xahz7 delta 38 pcmcb>{Em6U1xC4IhC+rMhD?SMhExV)20I2@AgKq$ra;nw0RYOh2g?8e From daeb751ad929c217e1a332fca14389a7ef7aa9f7 Mon Sep 17 00:00:00 2001 From: halfbug Date: Fri, 10 May 2024 19:09:52 +0500 Subject: [PATCH 09/11] just open ai integration --- app/api/v1/llm.py | 3 ++- app/utils/llm/tools/reverse.py | 8 ++++++++ requirements.txt | Bin 464 -> 408 bytes 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 app/utils/llm/tools/reverse.py diff --git a/app/api/v1/llm.py b/app/api/v1/llm.py index 48f3ce7..1d0d08d 100644 --- a/app/api/v1/llm.py +++ b/app/api/v1/llm.py @@ -4,6 +4,7 @@ from app.utils.llm.conversation_agent import ConversationAgent from app.utils.llm.openai_model import OpenAIModel +from app.utils.llm.tools.reverse import create_your_own from app.utils.llm.tools.web_search import search_web router = APIRouter() @@ -25,7 +26,7 @@ async def prompt(request_data: PromptRequest): try: reply_message = f"You said: {request_data.message}" - tools = [search_web] # Define your tools + tools = [create_your_own] # Define your tools workroom_modal = OpenAIModel(tools=tools) # Initialize the OpenAI model conversation_agent = ConversationAgent(openai_model=workroom_modal, tools=tools) diff --git a/app/utils/llm/tools/reverse.py b/app/utils/llm/tools/reverse.py new file mode 100644 index 0000000..db4cc2f --- /dev/null +++ b/app/utils/llm/tools/reverse.py @@ -0,0 +1,8 @@ +from langchain.tools import tool + + +@tool +def create_your_own(query: str) -> str: + """This function can do whatever you would like once you fill it in""" + print(type(query)) + return query[::-1] diff --git a/requirements.txt b/requirements.txt index 5f5387e234bfc7ff0594c4c495948e656e48e7e1..533d68e2d7a011b51e13e4d7fbe33905648425c6 100644 GIT binary patch delta 11 Scmcb>JcD_I4CCYw#u@+@%mbhR delta 44 qcmbQie1Um`3?qLsLk2?;Lq0<;Ln1>8L(;^z;=J(;NP?5a85;osNeeOn From 4aaa51f3bbc3b7f3f46d9f717b182e3380ad5eef Mon Sep 17 00:00:00 2001 From: Sadaf Siddiqui <92418104+sadafgs@users.noreply.github.com> Date: Fri, 10 May 2024 19:18:13 +0500 Subject: [PATCH 10/11] just open ai integration (#20) Co-authored-by: halfbug --- app/api/v1/llm.py | 3 ++- app/utils/llm/tools/reverse.py | 8 ++++++++ requirements.txt | Bin 464 -> 408 bytes 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 app/utils/llm/tools/reverse.py diff --git a/app/api/v1/llm.py b/app/api/v1/llm.py index 48f3ce7..1d0d08d 100644 --- a/app/api/v1/llm.py +++ b/app/api/v1/llm.py @@ -4,6 +4,7 @@ from app.utils.llm.conversation_agent import ConversationAgent from app.utils.llm.openai_model import OpenAIModel +from app.utils.llm.tools.reverse import create_your_own from app.utils.llm.tools.web_search import search_web router = APIRouter() @@ -25,7 +26,7 @@ async def prompt(request_data: PromptRequest): try: reply_message = f"You said: {request_data.message}" - tools = [search_web] # Define your tools + tools = [create_your_own] # Define your tools workroom_modal = OpenAIModel(tools=tools) # Initialize the OpenAI model conversation_agent = ConversationAgent(openai_model=workroom_modal, tools=tools) diff --git a/app/utils/llm/tools/reverse.py b/app/utils/llm/tools/reverse.py new file mode 100644 index 0000000..db4cc2f --- /dev/null +++ b/app/utils/llm/tools/reverse.py @@ -0,0 +1,8 @@ +from langchain.tools import tool + + +@tool +def create_your_own(query: str) -> str: + """This function can do whatever you would like once you fill it in""" + print(type(query)) + return query[::-1] diff --git a/requirements.txt b/requirements.txt index 5f5387e234bfc7ff0594c4c495948e656e48e7e1..533d68e2d7a011b51e13e4d7fbe33905648425c6 100644 GIT binary patch delta 11 Scmcb>JcD_I4CCYw#u@+@%mbhR delta 44 qcmbQie1Um`3?qLsLk2?;Lq0<;Ln1>8L(;^z;=J(;NP?5a85;osNeeOn From c360f6fc0016263bfdd3761c35699efde2ab7ba4 Mon Sep 17 00:00:00 2001 From: halfbug Date: Fri, 10 May 2024 19:36:58 +0500 Subject: [PATCH 11/11] switch off search --- app/api/v1/llm.py | 2 +- app/utils/llm/tools/web_search.py | 51 +++++++++++++++++-------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/app/api/v1/llm.py b/app/api/v1/llm.py index 1d0d08d..902ff83 100644 --- a/app/api/v1/llm.py +++ b/app/api/v1/llm.py @@ -5,7 +5,7 @@ from app.utils.llm.conversation_agent import ConversationAgent from app.utils.llm.openai_model import OpenAIModel from app.utils.llm.tools.reverse import create_your_own -from app.utils.llm.tools.web_search import search_web + router = APIRouter() diff --git a/app/utils/llm/tools/web_search.py b/app/utils/llm/tools/web_search.py index 40d3b9f..e0142c5 100644 --- a/app/utils/llm/tools/web_search.py +++ b/app/utils/llm/tools/web_search.py @@ -1,12 +1,14 @@ import os -from langchain.chains import RetrievalQAWithSourcesChain -from langchain.retrievers.web_research import WebResearchRetriever -from langchain.tools import tool -from langchain_chroma import Chroma -from langchain_community.utilities import GoogleSearchAPIWrapper -from langchain_openai import ChatOpenAI, OpenAIEmbeddings -from bs4 import BeautifulSoup +# from langchain.chains import RetrievalQAWithSourcesChain +# from langchain.retrievers.web_research import WebResearchRetriever +# from langchain.tools import tool +# # from langchain.vectorstores import pgvector +# # from langchain_chroma import Chroma +# from langchain_community.utilities import GoogleSearchAPIWrapper +# from langchain_community.vectorstores import FAISS +# from langchain_openai import ChatOpenAI, OpenAIEmbeddings + from app.core.config import config os.environ["GOOGLE_API_KEY"] = config.GOOGLE_API_KEY @@ -14,7 +16,7 @@ os.environ["OPENAI_API_KEY"] = config.OPENAI_API_KEY -@tool +# @tool def search_web(query): """ Performs search on Google Shopping. @@ -24,24 +26,27 @@ def search_web(query): Returns: - search results: string return. """ - vectorstore = Chroma( - embedding_function=OpenAIEmbeddings(), persist_directory="./chroma_db_oai" - ) + # vectorstore = Chroma( + # embedding_function=OpenAIEmbeddings(), persist_directory="./chroma_db_oai" + # ) + + # vectorstore = FAISS(embedding_function=OpenAIEmbeddings()) - # LLM - llm = ChatOpenAI(openai_api_key=config.OPENAI_API_KEY, temperature=0) + # # LLM + # llm = ChatOpenAI(openai_api_key=config.OPENAI_API_KEY, temperature=0) - # Search - search = GoogleSearchAPIWrapper() + # # Search + # search = GoogleSearchAPIWrapper() - # Initialize - web_research_retriever = WebResearchRetriever.from_llm( - vectorstore=vectorstore, llm=llm, search=search - ) + # # Initialize + # web_research_retriever = WebResearchRetriever.from_llm( + # vectorstore=vectorstore, llm=llm, search=search + # ) - qa_chain = RetrievalQAWithSourcesChain.from_chain_type( - llm, retriever=web_research_retriever - ) + # qa_chain = RetrievalQAWithSourcesChain.from_chain_type( + # llm, retriever=web_research_retriever + # ) - result = qa_chain({"question": query}) + # result = qa_chain({"question": query}) + result = True return result