From 011a96a5c9f692e7a0677988d7bccab9f66995a8 Mon Sep 17 00:00:00 2001 From: Subhash Vadadoriya Date: Tue, 7 May 2024 12:07:18 +0530 Subject: [PATCH 01/12] Update app.yaml (#15) --- app.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.yaml b/app.yaml index b1141af..1c70fd8 100644 --- a/app.yaml +++ b/app.yaml @@ -5,7 +5,7 @@ entrypoint: uvicorn app.main:app handlers: - url: /.* - script: auto + script: main.py vpc_access_connector: name: projects/hip-arcadia-419017/locations/us-central1/connectors/workroom-alloydb From 5824e1681aff16712993dba65fc08c933ca23807 Mon Sep 17 00:00:00 2001 From: Subhash Vadadoriya Date: Tue, 7 May 2024 12:12:25 +0530 Subject: [PATCH 02/12] Update app.yaml --- app.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app.yaml b/app.yaml index 1c70fd8..67c97c5 100644 --- a/app.yaml +++ b/app.yaml @@ -1,12 +1,10 @@ service: api-workroom runtime: python39 -entrypoint: uvicorn app.main:app - +entrypoint: uvicorn main:app --host=0.0.0.0 --port=${PORT} --log-level=info handlers: - url: /.* - script: main.py + script: auto vpc_access_connector: name: projects/hip-arcadia-419017/locations/us-central1/connectors/workroom-alloydb - From 66925c9505209dc63ff5293d65126de28fda2deb Mon Sep 17 00:00:00 2001 From: Subhash Vadadoriya Date: Tue, 7 May 2024 12:18:17 +0530 Subject: [PATCH 03/12] Update main.py --- main.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index e4a2dfd..1bb220e 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,7 @@ -import uvicorn +from fastapi import FastAPI + +app = FastAPI() if __name__ == "__main__": - uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True) \ No newline at end of file + import uvicorn + uvicorn.run("main:app", host="127.0.0.1", port=8080, log_level="info") From 5062359e57406be77995f205975dbfc013dc1d44 Mon Sep 17 00:00:00 2001 From: halfbug Date: Tue, 7 May 2024 11:58:09 +0500 Subject: [PATCH 04/12] add app to main --- app.yaml | 3 ++- main.py | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app.yaml b/app.yaml index 67c97c5..3210798 100644 --- a/app.yaml +++ b/app.yaml @@ -1,6 +1,6 @@ service: api-workroom runtime: python39 -entrypoint: uvicorn main:app --host=0.0.0.0 --port=${PORT} --log-level=info +entrypoint: uvicorn app.main:app --host=0.0.0.0 --port=${PORT} --log-level=info handlers: - url: /.* @@ -8,3 +8,4 @@ handlers: vpc_access_connector: name: projects/hip-arcadia-419017/locations/us-central1/connectors/workroom-alloydb + \ No newline at end of file diff --git a/main.py b/main.py index 1bb220e..e6e169a 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,5 @@ -from fastapi import FastAPI - -app = FastAPI() +import uvicorn if __name__ == "__main__": - import uvicorn - uvicorn.run("main:app", host="127.0.0.1", port=8080, log_level="info") + + uvicorn.run("app.main:app", host="127.0.0.1", port=8080, log_level="info") 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 05/12] 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 06/12] 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 07/12] 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 08/12] 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 09/12] 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 10/12] 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 11/12] 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 12/12] 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