| import os |
| import streamlit as st |
| import logging |
| from langchain_groq import ChatGroq |
| from langchain_community.tools import ArxivQueryRun, WikipediaQueryRun, DuckDuckGoSearchRun |
| from langchain_community.utilities import ArxivAPIWrapper, WikipediaAPIWrapper |
| from langchain import hub |
| from langchain.agents import create_openai_tools_agent, AgentExecutor |
| from langchain.prompts import PromptTemplate |
| from langchain_community.vectorstores import FAISS |
| from langchain_huggingface import HuggingFaceEmbeddings |
| from langchain.tools import Tool |
| from pydantic import BaseModel, Field |
| from typing import List, Dict |
|
|
| |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') |
| logging.info("Streamlit app started") |
|
|
| |
| groq_api_key = "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" |
| if not groq_api_key: |
| logging.error("GROQ API key is missing!") |
|
|
| |
| condense_prompt_template = PromptTemplate( |
| input_variables=["original_question", "conversation_history"], |
| template=""" |
| Given the conversation history below, condense the user's query into a clear and specific question. |
| Conversation History: |
| {conversation_history} |
| Original Question: |
| {original_question} |
| Condensed Question:""" |
| ) |
|
|
| def condense_query(llm_model, original_question, conversation_history): |
| prompt = condense_prompt_template.format( |
| original_question=original_question, |
| conversation_history=conversation_history |
| ) |
| resp = llm_model.predict(prompt) |
| return resp.strip() |
|
|
| |
| embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2") |
| vector_db = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True) |
| retriever_tool = vector_db.as_retriever() |
|
|
| |
| class RetrieveDocumentsInput(BaseModel): |
| query: str = Field(..., description="Query to retrieve relevant documents.") |
|
|
| class RetrieveDocumentsOutput(BaseModel): |
| documents: List[Dict[str, str]] = Field(..., description="List of retrieved documents, each containing 'content'.") |
|
|
| |
| def retrieve_documents(query: str) -> List[Dict[str, str]]: |
| results = retriever_tool.get_relevant_documents(query) |
| return [{"content": doc.page_content} for doc in results] |
|
|
| |
| faiss_tool = Tool( |
| name="retrieve_documents", |
| description="Retrieve documents from FAISS vectorstore.", |
| func=retrieve_documents, |
| ) |
|
|
| |
| arxiv_wrapper = ArxivAPIWrapper(top_k_results=1, doc_content_chars_max=250) |
| arxiv_tool = ArxivQueryRun(api_wrapper=arxiv_wrapper) |
|
|
| wiki_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=250) |
| wiki_tool = WikipediaQueryRun(api_wrapper=wiki_wrapper) |
|
|
| search_tool = DuckDuckGoSearchRun(name="Search") |
| tools = [arxiv_tool, wiki_tool, search_tool, faiss_tool] |
|
|
| |
| prompt = hub.pull("hwchase17/openai-functions-agent") |
| llm = ChatGroq(model="mixtral-8x7b-32768", api_key=groq_api_key, streaming=True) |
| agent = create_openai_tools_agent(llm, tools, prompt) |
| agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True) |
|
|
| |
| if 'messages' not in st.session_state: |
| st.session_state['messages'] = [{"role": "assistant", "content": "How can I help you?"}] |
|
|
| |
| for msg in st.session_state['messages']: |
| st.chat_message(msg["role"]).write(msg["content"]) |
|
|
| |
| conversation_history = "\n".join( |
| [f"{msg['role']}: {msg['content']}" for msg in st.session_state['messages']] |
| ) |
|
|
| |
| st.markdown(""" |
| <style> |
| .fixed-bottom-input-container { |
| position: fixed; |
| bottom: 0; |
| width: 100%; |
| background-color: white; |
| padding: 10px 0; |
| border-top: 1px solid #ddd; |
| } |
| .fixed-bottom-input { |
| width: 100%; |
| padding: 10px; |
| font-size: 16px; |
| } |
| </style> |
| """, unsafe_allow_html=True) |
|
|
| |
| user_input = st.text_input("Type your message here...", key="user_input", label_visibility="collapsed") |
|
|
| |
| if user_input: |
| condensed_question = condense_query(llm, user_input, conversation_history) |
| |
| |
| response_placeholder = st.empty() |
| response_text = "" |
| |
| |
| for token in agent_executor.stream({"input": condensed_question}): |
| |
| if "output" in token: |
| response_text += token["output"] |
| response_placeholder.write(response_text) |
| else: |
| logging.warning("Received token without 'output' key: %s", token) |
| |
| |
| st.session_state.messages.append({"role": "user", "content": user_input}) |
| st.session_state.messages.append({"role": "assistant", "content": response_text}) |
| |
| |
| st.chat_message("user").write(user_input) |
| st.chat_message("assistant").write(response_text) |
| |
| |
| user_input = "" |
|
|
|
|