Download app.py from Ankit93/Agent: direct link, hf CLI and curl.
- Browser
- Download file 5.37 kB
-
https://huggingface.co/spaces/Ankit93/Agent/resolve/main/app.py
- Command line
-
hf download hf://spaces/Ankit93/Agent/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Ankit93/Agent/resolve/main/app.py
5.37 kB
| 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 | |
| # Configure logging | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| logging.info("Streamlit app started") | |
| # Load the API key | |
| groq_api_key = "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" #os.getenv("GROQ_API_KEY") | |
| if not groq_api_key: | |
| logging.error("GROQ API key is missing!") | |
| # Define a query condensing template | |
| 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() | |
| # Initialize HuggingFace embeddings and FAISS vectorstore | |
| 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() | |
| # Define input/output models for OpenAI function-calling compliance | |
| 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'.") | |
| # Wrapper function for FAISS retriever | |
| 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] | |
| # Define the FAISS tool | |
| faiss_tool = Tool( | |
| name="retrieve_documents", | |
| description="Retrieve documents from FAISS vectorstore.", | |
| func=retrieve_documents, | |
| ) | |
| # Initialize tools | |
| 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] | |
| # Set up the agent | |
| 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) | |
| # Initialize session state for messages | |
| if 'messages' not in st.session_state: | |
| st.session_state['messages'] = [{"role": "assistant", "content": "How can I help you?"}] | |
| # Display chat messages | |
| for msg in st.session_state['messages']: | |
| st.chat_message(msg["role"]).write(msg["content"]) | |
| # Extract conversation history | |
| conversation_history = "\n".join( | |
| [f"{msg['role']}: {msg['content']}" for msg in st.session_state['messages']] | |
| ) | |
| # CSS for input box at bottom of screen | |
| 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) | |
| # Chat input and processing | |
| user_input = st.text_input("Type your message here...", key="user_input", label_visibility="collapsed") | |
| # If there's input, process it | |
| if user_input: | |
| condensed_question = condense_query(llm, user_input, conversation_history) | |
| # Placeholder for streaming the assistant's response | |
| response_placeholder = st.empty() | |
| response_text = "" | |
| # Stream response tokens | |
| for token in agent_executor.stream({"input": condensed_question}): | |
| # Ensure the token contains the "output" key | |
| if "output" in token: | |
| response_text += token["output"] | |
| response_placeholder.write(response_text) | |
| else: | |
| logging.warning("Received token without 'output' key: %s", token) | |
| # Continue with the chat history and message updates | |
| st.session_state.messages.append({"role": "user", "content": user_input}) | |
| st.session_state.messages.append({"role": "assistant", "content": response_text}) | |
| # Display the user input and response | |
| st.chat_message("user").write(user_input) | |
| st.chat_message("assistant").write(response_text) | |
| # Reset the input box content | |
| user_input = "" | |