From 9e6d708f57e743e35178dcd0f65c6e3652eb1486 Mon Sep 17 00:00:00 2001 From: ericphann <55606574+ericphann@users.noreply.github.com> Date: Sun, 17 Nov 2024 12:56:47 -0500 Subject: [PATCH 1/2] Refactor directory structure and delete unused files --- .gitignore | 5 + backend/.DS_Store | Bin 6148 -> 0 bytes backend/{src => }/agent/__init__.py | 0 .../{src => }/agent/faiss_store/index.faiss | Bin backend/{src => }/agent/faiss_store/index.pkl | Bin 12327 -> 12327 bytes backend/{src => }/agent/graph.py | 12 +- backend/{src => }/agent/nodes/__init__.py | 0 backend/{src => }/agent/nodes/assistant.py | 2 +- backend/{src => }/agent/nodes/tool_node.py | 0 backend/{src => }/agent/rag.py | 0 .../agent/rag_datasets/charlotte_r1.md | 0 .../agent/rag_datasets/charlotte_r1/0.txt | 0 .../rag_datasets/restaurant_offerings.md | 0 .../rag_datasets/restaurant_offerings/1.txt | 0 backend/{src => }/agent/state.py | 2 +- backend/{src => }/agent/tools/__init__.py | 0 backend/{src => }/agent/tools/general.py | 2 +- backend/{src => }/agent/utils.py | 2 +- backend/{src => }/graph.txt | 0 backend/src/.DS_Store | Bin 6148 -> 0 bytes backend/src/api.py | 205 ------------------ backend/src/client.py | 82 ------- backend/{src => }/template_llama3.jinja | 0 dinebot_app.py | 4 +- frontend/.DS_Store | Bin 6148 -> 0 bytes frontend/app.py | 109 ---------- frontend/app1.py | 129 ----------- frontend/modal/app.py | 113 ---------- frontend/modal/graph.txt | 15 -- frontend/modal/serve_streamlit.py | 90 -------- graph.txt | 8 +- test_agent.py | 4 +- tests/unittest.py | 27 +-- 33 files changed, 32 insertions(+), 779 deletions(-) delete mode 100644 backend/.DS_Store rename backend/{src => }/agent/__init__.py (100%) rename backend/{src => }/agent/faiss_store/index.faiss (100%) rename backend/{src => }/agent/faiss_store/index.pkl (98%) rename backend/{src => }/agent/graph.py (91%) rename backend/{src => }/agent/nodes/__init__.py (100%) rename backend/{src => }/agent/nodes/assistant.py (96%) rename backend/{src => }/agent/nodes/tool_node.py (100%) rename backend/{src => }/agent/rag.py (100%) rename backend/{src => }/agent/rag_datasets/charlotte_r1.md (100%) rename backend/{src => }/agent/rag_datasets/charlotte_r1/0.txt (100%) rename backend/{src => }/agent/rag_datasets/restaurant_offerings.md (100%) rename backend/{src => }/agent/rag_datasets/restaurant_offerings/1.txt (100%) rename backend/{src => }/agent/state.py (86%) rename backend/{src => }/agent/tools/__init__.py (100%) rename backend/{src => }/agent/tools/general.py (98%) rename backend/{src => }/agent/utils.py (97%) rename backend/{src => }/graph.txt (100%) delete mode 100644 backend/src/.DS_Store delete mode 100644 backend/src/api.py delete mode 100644 backend/src/client.py rename backend/{src => }/template_llama3.jinja (100%) delete mode 100644 frontend/.DS_Store delete mode 100644 frontend/app.py delete mode 100644 frontend/app1.py delete mode 100644 frontend/modal/app.py delete mode 100644 frontend/modal/graph.txt delete mode 100644 frontend/modal/serve_streamlit.py diff --git a/.gitignore b/.gitignore index 7e76fd87..dbff0c29 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +# Visual Studio Code settings +.vscode/ + +.DS_STORE + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/backend/.DS_Store b/backend/.DS_Store deleted file mode 100644 index 220c1c2cdfc67b69cd7b97f6d1a94f5743e0a976..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKF=_)r43uIQhBPiy?iccd#W*kU2SRK}bNIj}sjter@-)v#Dq;>-CXE?^cJ{Oy zEjPvKWM;nkI=q^#&1?lH+7Fkx@ti)hr-~4rHTJ{DI1bp_VwQX(K<>iMcC!89{Ffi0 z@7?J*jK@zTv8qf8NC7Dz1*Cu!xLbj0sjKI^E2)4KkOGgU0KX3nPV9wKVthKV#0UUf zA{>T&%o4!H0I(NMiHN{FslcRqjToME#9QU{!YMK7=5aIX)XiQKipTAUw@5ediCU$A z6u4HPhV(W2{~P?q{C`c-lN68w52b)Fx4Z2IuT;Ht_HyjC4gL;i&M%yXeNeDOI|fEO h#sk~&OC)7p;~wX|a7qk1;z0-MXMnoMq`-eGZ~@d}7g7KK diff --git a/backend/src/agent/__init__.py b/backend/agent/__init__.py similarity index 100% rename from backend/src/agent/__init__.py rename to backend/agent/__init__.py diff --git a/backend/src/agent/faiss_store/index.faiss b/backend/agent/faiss_store/index.faiss similarity index 100% rename from backend/src/agent/faiss_store/index.faiss rename to backend/agent/faiss_store/index.faiss diff --git a/backend/src/agent/faiss_store/index.pkl b/backend/agent/faiss_store/index.pkl similarity index 98% rename from backend/src/agent/faiss_store/index.pkl rename to backend/agent/faiss_store/index.pkl index fb5b95f984a53575740baab0f17a7c4ecb4531f4..36d1e05ff32e1c55096c06ee8e76aab57d450c99 100644 GIT binary patch delta 129 zcmZ3UusmTxw2Gloie-{za;mP8sbz|;i7Aj}VPs;dYieR*lxCV{o|tnx>c<=$aT9rs!H4 f8>H%*0*x~=N-;>aNHW?SD!*NT8EDdEegg>rhG8eI diff --git a/backend/src/agent/graph.py b/backend/agent/graph.py similarity index 91% rename from backend/src/agent/graph.py rename to backend/agent/graph.py index f3ec2748..fbc67b30 100644 --- a/backend/src/agent/graph.py +++ b/backend/agent/graph.py @@ -7,11 +7,11 @@ import json import os from langchain_openai import ChatOpenAI -from backend.src.agent.state import State -from backend.src.agent.nodes.assistant import Assistant -from backend.src.agent.utils import create_tool_node_with_fallback -from backend.src.agent.tools.general import book_a_cab, book_a_table, answer_question -from backend.src.agent.rag import populate_vector_db, create_faiss_store +from backend.agent.state import State +from backend.agent.nodes.assistant import Assistant +from backend.agent.utils import create_tool_node_with_fallback +from backend.agent.tools.general import book_a_cab, book_a_table, answer_question +from backend.agent.rag import populate_vector_db, create_faiss_store token = os.environ.get("OPENAI_API_KEY") @@ -61,7 +61,7 @@ builder = StateGraph(State) routes: list = json.load( - open(os.path.dirname(os.path.abspath(__file__)) + "/../../../role-values.json") + open(os.path.dirname(os.path.abspath(__file__)) + "/../../role-values.json") ) diff --git a/backend/src/agent/nodes/__init__.py b/backend/agent/nodes/__init__.py similarity index 100% rename from backend/src/agent/nodes/__init__.py rename to backend/agent/nodes/__init__.py diff --git a/backend/src/agent/nodes/assistant.py b/backend/agent/nodes/assistant.py similarity index 96% rename from backend/src/agent/nodes/assistant.py rename to backend/agent/nodes/assistant.py index 1120f7ec..634a5110 100644 --- a/backend/src/agent/nodes/assistant.py +++ b/backend/agent/nodes/assistant.py @@ -1,5 +1,5 @@ from langchain_core.runnables import Runnable, RunnableConfig -from backend.src.agent.state import State +from backend.agent.state import State class Assistant: diff --git a/backend/src/agent/nodes/tool_node.py b/backend/agent/nodes/tool_node.py similarity index 100% rename from backend/src/agent/nodes/tool_node.py rename to backend/agent/nodes/tool_node.py diff --git a/backend/src/agent/rag.py b/backend/agent/rag.py similarity index 100% rename from backend/src/agent/rag.py rename to backend/agent/rag.py diff --git a/backend/src/agent/rag_datasets/charlotte_r1.md b/backend/agent/rag_datasets/charlotte_r1.md similarity index 100% rename from backend/src/agent/rag_datasets/charlotte_r1.md rename to backend/agent/rag_datasets/charlotte_r1.md diff --git a/backend/src/agent/rag_datasets/charlotte_r1/0.txt b/backend/agent/rag_datasets/charlotte_r1/0.txt similarity index 100% rename from backend/src/agent/rag_datasets/charlotte_r1/0.txt rename to backend/agent/rag_datasets/charlotte_r1/0.txt diff --git a/backend/src/agent/rag_datasets/restaurant_offerings.md b/backend/agent/rag_datasets/restaurant_offerings.md similarity index 100% rename from backend/src/agent/rag_datasets/restaurant_offerings.md rename to backend/agent/rag_datasets/restaurant_offerings.md diff --git a/backend/src/agent/rag_datasets/restaurant_offerings/1.txt b/backend/agent/rag_datasets/restaurant_offerings/1.txt similarity index 100% rename from backend/src/agent/rag_datasets/restaurant_offerings/1.txt rename to backend/agent/rag_datasets/restaurant_offerings/1.txt diff --git a/backend/src/agent/state.py b/backend/agent/state.py similarity index 86% rename from backend/src/agent/state.py rename to backend/agent/state.py index c2b02d0c..dbae594f 100644 --- a/backend/src/agent/state.py +++ b/backend/agent/state.py @@ -1,7 +1,7 @@ from typing import TypedDict, Annotated, Dict, Any, List # from langgraph.graph import add_messages -from backend.src.agent.utils import add_messages_to_dict +from backend.agent.utils import add_messages_to_dict from langchain_core.messages import AnyMessage diff --git a/backend/src/agent/tools/__init__.py b/backend/agent/tools/__init__.py similarity index 100% rename from backend/src/agent/tools/__init__.py rename to backend/agent/tools/__init__.py diff --git a/backend/src/agent/tools/general.py b/backend/agent/tools/general.py similarity index 98% rename from backend/src/agent/tools/general.py rename to backend/agent/tools/general.py index 787e5510..3ed0e040 100644 --- a/backend/src/agent/tools/general.py +++ b/backend/agent/tools/general.py @@ -10,7 +10,7 @@ from langchain.schema import StrOutputParser from langchain.schema.runnable import RunnablePassthrough from langchain_core.prompts import ChatPromptTemplate -from backend.src.agent.rag import load_faiss_store +from backend.agent.rag import load_faiss_store # from openai import OpenAI from langchain_openai import OpenAI, OpenAIEmbeddings diff --git a/backend/src/agent/utils.py b/backend/agent/utils.py similarity index 97% rename from backend/src/agent/utils.py rename to backend/agent/utils.py index d09a13fd..64feee47 100644 --- a/backend/src/agent/utils.py +++ b/backend/agent/utils.py @@ -1,6 +1,6 @@ from langchain_core.messages import ToolMessage from langchain_core.runnables import RunnableLambda -from backend.src.agent.nodes.tool_node import ToolNode +from backend.agent.nodes.tool_node import ToolNode from langgraph.graph import add_messages from typing import Union diff --git a/backend/src/graph.txt b/backend/graph.txt similarity index 100% rename from backend/src/graph.txt rename to backend/graph.txt diff --git a/backend/src/.DS_Store b/backend/src/.DS_Store deleted file mode 100644 index d37db7efc76d69ec1fc3d7f3c01c73053b3c9a6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~J#GR)425k15)ut%%4s+NHyEMi1YCe5i)auOKtD(4`A0~*P)AYpEZJ|yV}tf9 zcGe=In|r?&S&GOUZYnDaBU9{W@+C(($XRav_2=|`xtzRelC@R?$8QYJ^O!;cBtQZr zKmsK2hX~lc4Vy1Q8A*TyNZ?7p-VX(CT2ou7zd8_n1b|MFcEj3d323ndw5GODWMCSt z&}da3LoDy@(2{jEwS`8zXbvBm|ExB}z%<%L3pOyVE(|0<0wV$+v0vK#zlFb>|3@v{ zk^l+(GXgs8cHIUKm3QmQ<5_;6Sz9+a)XNbD9|73dRs0Ee!+Eg 20s) - ) - - engine = AsyncLLMEngine.from_engine_args( - engine_args, usage_context=UsageContext.OPENAI_API_SERVER - ) - - api_server.openai_serving_chat = OpenAIServingChat( - engine, - served_model_names=[MODEL_DIR], - response_role="assistant", - lora_modules=[], - chat_template="chat_template.jinja", - ) - api_server.openai_serving_completion = OpenAIServingCompletion( - engine, served_model_names=[MODEL_DIR], lora_modules=[] - ) - - return app - - -# ## Deploy the server -# -# To deploy the API on Modal, just run -# ```bash -# modal deploy api.py -# ``` -# -# This will create a new app on Modal, build the container image for it, and deploy. -# -# ### Interact with the server -# -# Once it is deployed, you'll see a URL appear in the command line, -# something like `https://your-workspace-name--vllm-openai-compatible-serve.modal.run`. -# -# You can find [interactive Swagger UI docs](https://swagger.io/tools/swagger-ui/) -# at the `/docs` route of that URL, i.e. `https://your-workspace-name--vllm-openai-compatible-serve.modal.run/docs`. -# These docs describe each route and indicate the expected input and output. -# -# For simple routes like `/health`, which checks whether the server is responding, -# you can even send a request directly from the docs. -# -# To interact with the API programmatically, you can use the Python `openai` library. -# -# See the small test `client.py` script included with this example for details. -# -# ```bash -# # pip install openai==1.13.3 -# python client.py -# ``` diff --git a/backend/src/client.py b/backend/src/client.py deleted file mode 100644 index ae264509..00000000 --- a/backend/src/client.py +++ /dev/null @@ -1,82 +0,0 @@ -"""This simple script shows how to interact with an OpenAI-compatible server from a client.""" - -import modal -import os -from openai import OpenAI - -from dotenv import load_dotenv - -load_dotenv() -base_url = os.environ.get("MODAL_BASE_URL") - - -class Colors: - """ANSI color codes""" - - GREEN = "\033[0;32m" - BLUE = "\033[0;34m" - GRAY = "\033[0;90m" - BOLD = "\033[1m" - END = "\033[0m" - - -client = OpenAI(api_key=os.environ.get("DSBA_LLAMA3_KEY")) - -WORKSPACE = modal.config._profile - -client.base_url = f"{base_url}" - -print( - Colors.GREEN, - Colors.BOLD, - f"🧠: Looking up available models on server at {client.base_url}. This may trigger a boot!", - Colors.END, - sep="", -) -model = client.models.list().data[0] - -print( - Colors.GREEN, - Colors.BOLD, - f"🧠: Requesting completion from model {model.id}", - Colors.END, - sep="", -) - -messages = [ - { - "role": "system", - "content": "You are a poetic assistant, skilled in writing satirical doggerel with creative flair.", - }, - { - "role": "user", - "content": "Compose a limerick about baboons and racoons.", - }, -] - -for message in messages: - color = Colors.GRAY - emoji = "👉" - if message["role"] == "user": - color = Colors.GREEN - emoji = "👤" - elif message["role"] == "assistant": - color = Colors.BLUE - emoji = "🤖" - print( - color, - f"{emoji}: {message['content']}", - Colors.END, - sep="", - ) - -stream = client.chat.completions.create( - model=model.id, - messages=messages, - stream=True, -) -print(Colors.BLUE, "🤖:", sep="", end="") -for chunk in stream: - if chunk.choices[0].delta.content is not None: - print(chunk.choices[0].delta.content, end="") -print(Colors.END) diff --git a/backend/src/template_llama3.jinja b/backend/template_llama3.jinja similarity index 100% rename from backend/src/template_llama3.jinja rename to backend/template_llama3.jinja diff --git a/dinebot_app.py b/dinebot_app.py index 66e5f9ae..d665f3b8 100644 --- a/dinebot_app.py +++ b/dinebot_app.py @@ -1,7 +1,7 @@ import re import streamlit as st -from backend.src.agent.graph import graph -from backend.src.agent.utils import _print_event +from backend.agent.graph import graph +from backend.agent.utils import _print_event from langchain_core.messages import ToolMessage, HumanMessage, AIMessage from langchain_core.output_parsers import StrOutputParser import uuid diff --git a/frontend/.DS_Store b/frontend/.DS_Store deleted file mode 100644 index 0be51ac4f873564eeea05fc25addc8a07a34adc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~J#ND=422(?1SpUtV@EALKyDxe&Ix*fr1j{+Ly=ua&m+YpZs)=X9s%l!l<1#t zuuK4Ux{XKR0N|DGigzCtW{h|E#*7hHOykej^f}Lyr}2_|J)rX%kL$TC5djep0TB=Z z5m*s{IK+AW?^pCpdK3{5fprk@??a)x*3{NDJ{=sQ1)y%34&yv}32N~KwWhYN%+M^m z2g_26HpKH$PA$2wrnauV9G1<8<(;4?h76{3w2-hjG35gj!QuS7vDX5eN(# JMBrZu+yV8H6Mp~z diff --git a/frontend/app.py b/frontend/app.py deleted file mode 100644 index 4cad2c75..00000000 --- a/frontend/app.py +++ /dev/null @@ -1,109 +0,0 @@ -import streamlit as st -from openai import OpenAI -import requests -import time -import toml - -st.title("Modal Llama 3 Instruct Deployment") - -api_url = st.secrets["MODAL_BASE_URL"] + "/v1" - -# Set API key from Streamlit secrets -client = OpenAI(api_key=st.secrets["DSBA_LLAMA3_KEY"], base_url=api_url) - -if "openai_model" not in st.session_state: - st.session_state["openai_model"] = "/models/NousResearch/Meta-Llama-3-8B-Instruct" - -# Initialize chat history -if "messages" not in st.session_state: - st.session_state.messages = [] - - -# Function to check API health -def check_api_health(): - try: - headers = {"Authorization": f"Bearer {st.secrets['DSBA_LLAMA3_KEY']}"} - response = requests.get( - f"{st.secrets['MODAL_BASE_URL']}/health", headers=headers, timeout=5 - ) - return response.status_code == 200 - except requests.RequestException: - return False - - -# Sidebar -st.sidebar.title("Chat Settings") - -# Model parameters -temperature = st.sidebar.slider("Temperature", 0.0, 2.0, 0.7, 0.1) -max_tokens = st.sidebar.slider("Max Tokens", 50, 2000, 1000, 50) -top_p = st.sidebar.slider("Top P", 0.0, 1.0, 1.0, 0.1) -presence_penalty = st.sidebar.slider("Presence Penalty", -2.0, 2.0, 0.0, 0.1) -frequency_penalty = st.sidebar.slider("Frequency Penalty", -2.0, 2.0, 0.0, 0.1) - -# System prompt -system_prompt = st.sidebar.text_area("System Prompt", "You are a helpful assistant.") - -# Reset button -if st.sidebar.button("Reset Chat"): - st.session_state.messages = [] - st.sidebar.success("Chat session reset!") - -# Check API health and display warning if not healthy -api_healthy = check_api_health() -if not api_healthy: - st.warning( - "Warning: The API endpoint is currently unavailable. Some features may not work properly." - ) - -# Display chat messages from history on app rerun -for message in st.session_state.messages: - with st.chat_message(message["role"]): - st.markdown(message["content"]) - -# Accept user input -if prompt := st.chat_input("What is up?"): - # Add user message to chat history - st.session_state.messages.append({"role": "user", "content": prompt}) - # Display user message in chat message container - with st.chat_message("user"): - st.markdown(prompt) - - start_time = time.time() - # Display assistant response in chat message container - with st.chat_message("assistant"): - message_placeholder = st.empty() - full_response = "" - try: - stream = client.chat.completions.create( - model=st.session_state["openai_model"], - messages=[{"role": "system", "content": system_prompt}] - + [ - {"role": m["role"], "content": m["content"]} - for m in st.session_state.messages - ], - stream=True, - temperature=temperature, - max_tokens=max_tokens, - top_p=top_p, - presence_penalty=presence_penalty, - frequency_penalty=frequency_penalty, - ) - for chunk in stream: - full_response += chunk.choices[0].delta.content or "" - message_placeholder.markdown(full_response + "▌") - message_placeholder.markdown(full_response) - - # Add latency print statement - end_time = time.time() - latency = end_time - start_time - tokens = len(full_response.split()) + 1 - st.info(f"Latency: {tokens / latency:.2f} tokens per seconds") - - except Exception as e: - st.error(f"An error occurred: {str(e)}") - full_response = ( - "I apologize, but I encountered an error while processing your request." - ) - - st.session_state.messages.append({"role": "assistant", "content": full_response}) diff --git a/frontend/app1.py b/frontend/app1.py deleted file mode 100644 index 7718a5fe..00000000 --- a/frontend/app1.py +++ /dev/null @@ -1,129 +0,0 @@ -import streamlit as st -import pandas as pd -from datetime import datetime -import random - - -def init_session_state(): - if "messages" not in st.session_state: - st.session_state.messages = [] - if "current_case" not in st.session_state: - st.session_state.current_case = None - if "cases" not in st.session_state: - st.session_state.cases = [] - - -def generate_case_number(): - return f"CASE-{datetime.now().strftime('%Y%m%d')}-{random.randint(1000, 9999)}" - - -def create_new_case(case_type, description): - case = { - "case_number": generate_case_number(), - "type": case_type, - "status": "New", - "assigned_agent": "Unassigned", - "description": description, - "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), - } - st.session_state.cases.append(case) - return case - - -def main(): - st.set_page_config(page_title="Multi-Agent Support System", layout="wide") - init_session_state() - - # Sidebar for case management - with st.sidebar: - st.title("Case Management") - - # New Case Creation - st.subheader("Create New Case") - case_type = st.selectbox( - "Case Type", - ["Deposit Operations", "Investment Operations", "General Inquiry"], - ) - case_description = st.text_area("Case Description") - if st.button("Create Case"): - new_case = create_new_case(case_type, case_description) - st.session_state.current_case = new_case - st.success(f"Created case: {new_case['case_number']}") - - # Case List - st.subheader("Active Cases") - for case in st.session_state.cases: - if st.button( - f"{case['case_number']} - {case['type']}", key=case["case_number"] - ): - st.session_state.current_case = case - - # Main chat interface - st.title("Multi-Agent Support System") - - # Current Case Information - if st.session_state.current_case: - col1, col2, col3 = st.columns(3) - with col1: - st.metric("Case Number", st.session_state.current_case["case_number"]) - with col2: - st.metric("Status", st.session_state.current_case["status"]) - with col3: - st.metric("Assigned Agent", st.session_state.current_case["assigned_agent"]) - - # Agent Selection - agent_type = st.selectbox( - "Select Agent Type", - [ - "Deposit Ops Agent", - "Invest Ops Agent", - "Deposit Supervisor", - "General Agent", - ], - ) - - # Chat Interface - for message in st.session_state.messages: - with st.chat_message(message["role"]): - st.markdown(message["content"]) - - if prompt := st.chat_input("Type your message here..."): - # Add user message - st.session_state.messages.append({"role": "user", "content": prompt}) - with st.chat_message("user"): - st.markdown(prompt) - - # Simulate agent response (replace with actual agent logic) - response = f"[{agent_type}] Response to: {prompt}" - st.session_state.messages.append({"role": "assistant", "content": response}) - with st.chat_message("assistant"): - st.markdown(response) - - # Update case status (simplified) - st.session_state.current_case["status"] = "In Progress" - st.session_state.current_case["assigned_agent"] = agent_type - - # Case Actions - col1, col2, col3 = st.columns(3) - with col1: - if st.button("Mark as Resolved"): - st.session_state.current_case["status"] = "Resolved" - with col2: - if st.button("Escalate Case"): - st.session_state.current_case["status"] = "Escalated" - with col3: - if st.button("Reset Chat"): - st.session_state.messages = [] - - else: - st.info("Please select or create a case to start chatting") - - # Display all cases in a table - st.subheader("Case Overview") - if st.session_state.cases: - df = pd.DataFrame(st.session_state.cases) - st.dataframe(df, hide_index=True) - - -if __name__ == "__main__": - main() diff --git a/frontend/modal/app.py b/frontend/modal/app.py deleted file mode 100644 index dadc14db..00000000 --- a/frontend/modal/app.py +++ /dev/null @@ -1,113 +0,0 @@ -import streamlit as st -from openai import OpenAI -from dotenv import load_dotenv -import requests -import time -import toml -import os - -st.title("Charlotte Eatz") - -load_dotenv() - -# base_url = os.environ.get("MODAL_BASE_URL") -token = os.environ.get("OPENAI_API_KEY") -# api_url = base_url + "/v1" - -# Set API key from Streamlit secrets -client = OpenAI(api_key=token) - -if "openai_model" not in st.session_state: - st.session_state["openai_model"] = "gpt-3.5-turbo" - -# Initialize chat history -if "messages" not in st.session_state: - st.session_state.messages = [] - - -# Function to check API health -def check_api_health(): - try: - headers = {"Authorization": f"Bearer {token}"} - response = requests.get(f"/health", headers=headers, timeout=5) - return response.status_code == 200 - except requests.RequestException: - return False - - -# Sidebar -st.sidebar.title("Chat Settings") - -# Model parameters -temperature = st.sidebar.slider("Temperature", 0.0, 2.0, 0.7, 0.1) -max_tokens = st.sidebar.slider("Max Tokens", 50, 2000, 1000, 50) -top_p = st.sidebar.slider("Top P", 0.0, 1.0, 1.0, 0.1) -presence_penalty = st.sidebar.slider("Presence Penalty", -2.0, 2.0, 0.0, 0.1) -frequency_penalty = st.sidebar.slider("Frequency Penalty", -2.0, 2.0, 0.0, 0.1) - -# System prompt -system_prompt = st.sidebar.text_area("System Prompt", "You are a helpful assistant.") - -# Reset button -if st.sidebar.button("Reset Chat"): - st.session_state.messages = [] - st.sidebar.success("Chat session reset!") - -# Check API health and display warning if not healthy -api_healthy = check_api_health() -if not api_healthy: - st.warning( - "Warning: The API endpoint is currently unavailable. Some features may not work properly." - ) - -# Display chat messages from history on app rerun -for message in st.session_state.messages: - with st.chat_message(message["role"]): - st.markdown(message["content"]) - -# Accept user input -if prompt := st.chat_input("What is up?"): - # Add user message to chat history - st.session_state.messages.append({"role": "user", "content": prompt}) - # Display user message in chat message container - with st.chat_message("user"): - st.markdown(prompt) - - start_time = time.time() - # Display assistant response in chat message container - with st.chat_message("assistant"): - message_placeholder = st.empty() - full_response = "" - try: - stream = client.chat.completions.create( - model=st.session_state["openai_model"], - messages=[{"role": "system", "content": system_prompt}] - + [ - {"role": m["role"], "content": m["content"]} - for m in st.session_state.messages - ], - stream=True, - temperature=temperature, - max_tokens=max_tokens, - top_p=top_p, - presence_penalty=presence_penalty, - frequency_penalty=frequency_penalty, - ) - for chunk in stream: - full_response += chunk.choices[0].delta.content or "" - message_placeholder.markdown(full_response + "▌") - message_placeholder.markdown(full_response) - - # Add latency print statement - end_time = time.time() - latency = end_time - start_time - tokens = len(full_response.split()) + 1 - st.info(f"Latency: {tokens / latency:.2f} tokens per seconds") - - except Exception as e: - st.error(f"An error occurred: {str(e)}") - full_response = ( - "I apologize, but I encountered an error while processing your request." - ) - - st.session_state.messages.append({"role": "assistant", "content": full_response}) diff --git a/frontend/modal/graph.txt b/frontend/modal/graph.txt deleted file mode 100644 index 0ababdcf..00000000 --- a/frontend/modal/graph.txt +++ /dev/null @@ -1,15 +0,0 @@ - +-----------+ - | __start__ | - +-----------+ - . - . - . - +---------------+ - ....| General Agent |..... - .......... +---------------+. ........... - .......... ... ..... ........... - .......... ... ... ........... - ..... .. ... ...... -+-------------------------+ +--------------------------+ +-------------------------------+ +---------+ -| General Agent_rag_tools | | General Agent_safe_tools | | General Agent_sensitive_tools | | __end__ | -+-------------------------+ +--------------------------+ +-------------------------------+ +---------+ \ No newline at end of file diff --git a/frontend/modal/serve_streamlit.py b/frontend/modal/serve_streamlit.py deleted file mode 100644 index 88fd6315..00000000 --- a/frontend/modal/serve_streamlit.py +++ /dev/null @@ -1,90 +0,0 @@ -# --- -# deploy: true -# cmd: ["modal", "serve", "10_integrations/streamlit/serve_streamlit.py"] -# --- -# -# # Run and share Streamlit apps -# -# This example shows you how to run a Streamlit app with `modal serve`, and then deploy it as a serverless web app. -# -# ![example streamlit app](./streamlit.png) -# -# This example is structured as two files: -# -# 1. This module, which defines the Modal objects (name the script `serve_streamlit.py` locally). -# 2. `app.py`, which is any Streamlit script to be mounted into the Modal -# function ([download script](https://github.com/modal-labs/modal-examples/blob/main/10_integrations/streamlit/app.py)). - -import shlex -import subprocess -from pathlib import Path - -import modal - -# ## Define container dependencies -# -# The `app.py` script imports three third-party packages, so we include these in the example's -# image definition. - -image = modal.Image.debian_slim(python_version="3.11").pip_install( - "streamlit~=1.37.0", "openai==1.37.1", "python-dotenv==1.0.1" -) - -app = modal.App(name="modal-streamlit-chat", image=image) - -# ## Mounting the `app.py` script -# -# We can just mount the `app.py` script inside the container at a pre-defined path using a Modal -# [`Mount`](https://modal.com/docs/guide/local-data#mounting-directories). - -streamlit_script_local_path = Path(__file__).parent / "app.py" -streamlit_script_remote_path = Path("/root/app.py") - -if not streamlit_script_local_path.exists(): - raise RuntimeError( - "app.py not found! Place the script with your streamlit app in the same directory." - ) - -streamlit_script_mount = modal.Mount.from_local_file( - streamlit_script_local_path, - streamlit_script_remote_path, -) - -# ## Spawning the Streamlit server -# -# Inside the container, we will run the Streamlit server in a background subprocess using -# `subprocess.Popen`. We also expose port 8000 using the `@web_server` decorator. - - -@app.function( - allow_concurrent_inputs=100, - mounts=[streamlit_script_mount], - secrets=[ - modal.Secret.from_name("dsba-llama3-key"), - modal.Secret.from_name("modal-base-url"), - ], -) -@modal.web_server(8000) -def run(): - target = shlex.quote(str(streamlit_script_remote_path)) - cmd = f"streamlit run {target} --server.port 8000 --server.enableCORS=false --server.enableXsrfProtection=false" - subprocess.Popen(cmd, shell=True) - - -# ## Iterate and Deploy -# -# While you're iterating on your screamlit app, you can run it "ephemerally" with `modal serve`. This will -# run a local process that watches your files and updates the app if anything changes. -# -# ```shell -# modal serve serve_streamlit.py -# ``` -# -# Once you're happy with your changes, you can deploy your application with -# -# ```shell -# modal deploy serve_streamlit.py -# ``` -# -# If successful, this will print a URL for your app, that you can navigate to from -# your browser 🎉 . diff --git a/graph.txt b/graph.txt index b7d088df..5649a252 100644 --- a/graph.txt +++ b/graph.txt @@ -6,10 +6,10 @@ . +---------------+ ****| General Agent |..... - ********** +---------------+* ........... - ********** ... ***** ........... - ********** ... *** ........... - ***** .. *** ...... + ********** +---------------+. ........... + ********** *** ..... ........... + ********** *** ... ........... + ***** ** ... ...... +-------------------------+ +--------------------------+ +-------------------------------+ +---------+ | General Agent_rag_tools | | General Agent_safe_tools | | General Agent_sensitive_tools | | __end__ | +-------------------------+ +--------------------------+ +-------------------------------+ +---------+ \ No newline at end of file diff --git a/test_agent.py b/test_agent.py index 11a69fee..6e126f8b 100644 --- a/test_agent.py +++ b/test_agent.py @@ -1,5 +1,5 @@ -from backend.src.agent.graph import graph -from backend.src.agent.utils import _print_event +from backend.agent.graph import graph +from backend.agent.utils import _print_event import uuid from langchain_core.messages import ToolMessage diff --git a/tests/unittest.py b/tests/unittest.py index 5f8bd11f..bbc0d173 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -1,23 +1,14 @@ -import pytest -import os - -from unittest.mock import patch, MagicMock -from backend.src.agent.tools.general import book_a_cab, book_a_table, answer_question +from backend.agent.tools.general import book_a_cab, book_a_table, answer_question # # Test book_a_cab # def test_book_a_cab(): # result = book_a_cab("I need a taxi to go to the restaurant") # assert result == "your taxi has been booked", "Cab booking response is incorrect" # print("Test Passed: The cab booking response is correct") -from _pytest.debugging import pytestPDB as __pytestPDB -import trafaret as t def test_book_a_cab(): - boolean_field = t.ToBool result = book_a_cab("I need a taxi to go to the restaurant") - if result != "your taxi has been booked": - __pytestPDB().set_trace() # Start the debugger here assert result == "your taxi has been booked", "Cab booking response is incorrect" @@ -52,9 +43,9 @@ def test_book_a_cab(): # assert result == expected_response, f"Unexpected response for query: {input_query}" # # Additional Tests for answer_question with edge cases -# @patch("backend.src.agent.tools.general.OpenAI") # Mock OpenAI -# @patch("backend.src.agent.tools.general.OpenAIEmbeddings") # Mock OpenAIEmbeddings -# @patch("backend.src.agent.tools.general.FAISS.load_local") # Mock FAISS.load_local +# @patch("backend.agent.tools.general.OpenAI") # Mock OpenAI +# @patch("backend.agent.tools.general.OpenAIEmbeddings") # Mock OpenAIEmbeddings +# @patch("backend.agent.tools.general.FAISS.load_local") # Mock FAISS.load_local # @pytest.mark.parametrize("input_query, mock_docs, expected_response", [ # # Normal case # ("What is the capital of France?", [("Paris is the capital.", 0.9)], "This is the response from RAG"), @@ -103,8 +94,8 @@ def test_book_a_cab(): # mock_llm.invoke.assert_called_once() # # Test FAISS store load failure for empty query -# @patch("backend.src.agent.tools.general.OpenAIEmbeddings") # Mock OpenAIEmbeddings -# @patch("backend.src.agent.rag.FAISS.load_local") # Mock FAISS.load_local +# @patch("backend.agent.tools.general.OpenAIEmbeddings") # Mock OpenAIEmbeddings +# @patch("backend.agent.rag.FAISS.load_local") # Mock FAISS.load_local # def test_answer_question_empty_query_faiss_load_error(mock_faiss_load_local, mock_openai_embeddings): # # Mock environment variable # os.environ["OPENAI_API_KEY"] = "fake-api-key" @@ -117,9 +108,9 @@ def test_book_a_cab(): # answer_question("") # # Test FAISS store load with no documents -# @patch("backend.src.agent.tools.general.OpenAI") # Mock OpenAI -# @patch("backend.src.agent.tools.general.OpenAIEmbeddings") # Mock OpenAIEmbeddings -# @patch("backend.src.agent.tools.general.FAISS.load_local") # Mock FAISS.load_local +# @patch("backend.agent.tools.general.OpenAI") # Mock OpenAI +# @patch("backend.agent.tools.general.OpenAIEmbeddings") # Mock OpenAIEmbeddings +# @patch("backend.agent.tools.general.FAISS.load_local") # Mock FAISS.load_local # def test_answer_question_no_documents(mock_faiss_load_local, mock_openai_embeddings, mock_openai): # # Mock environment variable # os.environ["OPENAI_API_KEY"] = "fake-api-key" From a0d59dce3f8001602535a02076c847892ce48469 Mon Sep 17 00:00:00 2001 From: ericphann <55606574+ericphann@users.noreply.github.com> Date: Sun, 17 Nov 2024 13:01:20 -0500 Subject: [PATCH 2/2] Remove files that should have been gitignored --- .DS_Store | Bin 6148 -> 0 bytes .../test.cpython-311-pytest-8.3.3.pyc | Bin 7354 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store delete mode 100644 tests/__pycache__/test.cpython-311-pytest-8.3.3.pyc diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 9ef732ae6f56bad8c4d197342f8d1d49dc6cb4db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKyKcfj5Zq0WfA!;D$AE2=q?} z79RnC6NKIH?6U;0SO8cPhd@MN8dP9VHAf5$I^rekYT^(WbWy(<=j6?r6N>unh!-yx zt$|#r02R1Y;5oK)>;G%`KlA@3i90Gl1s+NPovb#iC0;3e>*(dI*B1C2{MS(HY~=b$7Yk<) zkMrKVc{B57_`dY#bUGox^Ec(6m4+e+|3akqNZrQcDl|S4h(JU`SQq)XRF9M;QK-x7 zQPJyB))n5PuB$}4C#=Uv1Yn%V028{pne2%r(R;!JKpyr8!g`7*z?CNAZ6T+Ajr7&B z-wO>DJ`wml{#@iM5!-?dt=_Zgw;h2Hk& z*Qh&y<`?Gj`7Oh!=dFfrYPEdXsy8&d zcE`~3Os89Vp>7e)DA1-^tm>L!S66mLSJ~2Ot+M^~7qEz3@km-++!b51Z(MF{&*WI* zx7|i|F^jFK94jzevzx3`wuqi+XBWMW`5bd&RA&v#WcqHzjQ}r#83gl3BN~Gh*j&a{ zUs)S~X$QpKWm%`WM8 z8-`|r#w;_Zx{)R|D4vg-#JRj3Ob3y&5p#6|88q7Us>V z;s&*vjoBjZlyO*SY`aOmaqo=icVIC7Tv-CH_l|IoxVf|ZkIck}&d1B2Mmw3pUZ$|0 zDeT-hRD|fIefeT1{C*igAITR_GI;!Zy)KW(N1@jrT4rb`3m>?*&Nmd~fkWTO}#*EUF`Sy-duBF(YJ0 zk3C7$iGi0%BX_@-35__`h#I!FL%8HH7a6%PaoZjz88Yg`yOut23QL~|OA2FMORs{Z zkF{lP>CddTmcO~B-|ej34C$oyaN z%>R|$6g`78jv+wzNY5b{NALoI2?Ub}@Fvg~5nKS^s$duin9$uMeF=$t3om2q6$Gy$ z$Rcf9pD-_#&kAlG!3t(n=GshO#3Ffz(x0XJ6H z8Phg&wkyzUun+E1ypSP&$0FM$qS+d~4m}vcusHxb0wil=OX64KFL&O&(Mi1x@4@(m z&gGwXQa9l}j7G*2hfyV^910$YDxRnED;yvNgE+3e6$tEjzT@k!Ee)yYh){hINc1x$ zTz`QYP9#v(k%`)dYK;@^#@mXc46W+K90lU-ICA&L+a&RnRh_=-%FwD#A0Je85~qve zhj2y1F*!+gt2&T}U}n*c^<$@q^%AILD;iW7H~?r9{P z#L(;~<|N=WARmEK>8r5~*=sz!rXgH?)hTkOoBbro7&+@CyBbNILL;g0d||AskvM21 z0eg;ol7c&a;t5v;+i7yH9fuvKw}dw8=A+OaFzMkB8Rxor0Xe^!Zpg$_-sg09w?pr9 zA0OQ32{PH$_y{>qUUWvf8dp!D@xJ^vyoR2}+X|u_Gr{NQBpyAu>7}M!wP>xyQ_q!Lgcji-T^Vywimu}n zx$KkU5I0h18#&RHYGy8w#e$8;gmxA(RT+&pEa**~8FJa#R{TDXb%`zL=oQ+AsRe}qk*QR-^y`