diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/__pycache__/__init__.cpython-311.pyc b/src/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..94a9504d1a032acd96f5d8164b56f3d400eb0747 Binary files /dev/null and b/src/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/__pycache__/__init__.cpython-313.pyc b/src/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..360b1f2aaf411532b0402eeed18bbd4a5bb3a7f9 Binary files /dev/null and b/src/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/langgraphagenticai/LLMS/__init__.py b/src/langgraphagenticai/LLMS/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/langgraphagenticai/LLMS/__pycache__/__init__.cpython-311.pyc b/src/langgraphagenticai/LLMS/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a630e89a3eb760029d607ed70ad6befbf547440 Binary files /dev/null and b/src/langgraphagenticai/LLMS/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/langgraphagenticai/LLMS/__pycache__/__init__.cpython-313.pyc b/src/langgraphagenticai/LLMS/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..143f125473774fe6368b5ed58ad617c64b8e0a27 Binary files /dev/null and b/src/langgraphagenticai/LLMS/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/langgraphagenticai/LLMS/__pycache__/groqllm.cpython-311.pyc b/src/langgraphagenticai/LLMS/__pycache__/groqllm.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd051c6e9589a82424e936ef21fc7a5754642d46 Binary files /dev/null and b/src/langgraphagenticai/LLMS/__pycache__/groqllm.cpython-311.pyc differ diff --git a/src/langgraphagenticai/LLMS/__pycache__/groqllm.cpython-313.pyc b/src/langgraphagenticai/LLMS/__pycache__/groqllm.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1ab4210ae1f6ab8f53ed0a67848b2404a658a620 Binary files /dev/null and b/src/langgraphagenticai/LLMS/__pycache__/groqllm.cpython-313.pyc differ diff --git a/src/langgraphagenticai/LLMS/groqllm.py b/src/langgraphagenticai/LLMS/groqllm.py new file mode 100644 index 0000000000000000000000000000000000000000..a6a2cb90c53ea58b241bb9208bb031843c3e0b88 --- /dev/null +++ b/src/langgraphagenticai/LLMS/groqllm.py @@ -0,0 +1,20 @@ +import os +import streamlit as st +from langchain_groq import ChatGroq + +class GroqLLM: + def __init__(self,user_contols_input): + self.user_controls_input=user_contols_input + + def get_llm_model(self): + try: + groq_api_key=self.user_controls_input["GROQ_API_KEY"] + selected_groq_model=self.user_controls_input["selected_groq_model"] + if groq_api_key=='' and os.environ["GROQ_API_KEY"] =='': + st.error("Please Enter the Groq API KEY") + + llm=ChatGroq(api_key=groq_api_key,model=selected_groq_model) + + except Exception as e: + raise ValueError(f"Error Ocuured With Exception : {e}") + return llm \ No newline at end of file diff --git a/src/langgraphagenticai/__init__.py b/src/langgraphagenticai/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/langgraphagenticai/__pycache__/__init__.cpython-311.pyc b/src/langgraphagenticai/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06674fab6b1c23655082220b4496ae40a41585bb Binary files /dev/null and b/src/langgraphagenticai/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/langgraphagenticai/__pycache__/__init__.cpython-313.pyc b/src/langgraphagenticai/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc4778606d6604ab14b2c7f6750dd114961628f0 Binary files /dev/null and b/src/langgraphagenticai/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/langgraphagenticai/__pycache__/main.cpython-311.pyc b/src/langgraphagenticai/__pycache__/main.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa8f549bfe317d4708dd591459ffcc6cb634afb6 Binary files /dev/null and b/src/langgraphagenticai/__pycache__/main.cpython-311.pyc differ diff --git a/src/langgraphagenticai/__pycache__/main.cpython-313.pyc b/src/langgraphagenticai/__pycache__/main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b14c266fab5b225fe33b3811c280c167e8c4c1ca Binary files /dev/null and b/src/langgraphagenticai/__pycache__/main.cpython-313.pyc differ diff --git a/src/langgraphagenticai/graph/__init__.py b/src/langgraphagenticai/graph/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/langgraphagenticai/graph/__pycache__/__init__.cpython-313.pyc b/src/langgraphagenticai/graph/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b7ac28765c157e03c09493acf3b6d3f568a691e Binary files /dev/null and b/src/langgraphagenticai/graph/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/langgraphagenticai/graph/__pycache__/graph_builder.cpython-313.pyc b/src/langgraphagenticai/graph/__pycache__/graph_builder.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..917064e8635f96163d989edaa32156fa30988f98 Binary files /dev/null and b/src/langgraphagenticai/graph/__pycache__/graph_builder.cpython-313.pyc differ diff --git a/src/langgraphagenticai/graph/graph_builder.py b/src/langgraphagenticai/graph/graph_builder.py new file mode 100644 index 0000000000000000000000000000000000000000..79197b21d469eb841788bcf6bbbdda326a094b1c --- /dev/null +++ b/src/langgraphagenticai/graph/graph_builder.py @@ -0,0 +1,122 @@ +from langgraph.graph import StateGraph +from src.langgraphagenticai.state.state import State +from langgraph.graph import START,END +from src.langgraphagenticai.nodes.basic_chatbot_node import BasicChatbotNode +from src.langgraphagenticai.tools.search_tool import get_tools,create_tool_node,get_tools_by_usecase +from langgraph.prebuilt import tools_condition,ToolNode +from src.langgraphagenticai.nodes.chatbot_with_Tool_node import ChatbotWithToolNode +from src.langgraphagenticai.nodes.ai_news_node import AINewsNode + +class GraphBuilder: + def __init__(self,model): + self.llm=model + self.graph_builder=StateGraph(State) + + def basic_chatbot_build_graph(self): + """ + Builds a basic chatbot graph using LangGraph. + This method initializes a chatbot node using the `BasicChatbotNode` class + and integrates it into the graph. The chatbot node is set as both the + entry and exit point of the graph. + """ + + self.basic_chatbot_node=BasicChatbotNode(self.llm) + + self.graph_builder.add_node("chatbot",self.basic_chatbot_node.process) + self.graph_builder.add_edge(START,"chatbot") + self.graph_builder.add_edge("chatbot",END) + + + def chatbot_with_tools_build_graph(self): + + """ + Builds an advanced chatbot graph with tool integration. + This method creates a chatbot graph that includes both a chatbot node + and a tool node. It defines tools, initializes the chatbot with tool + capabilities, and sets up conditional and direct edges between nodes. + The chatbot node is set as the entry point. + """ + ## Define the tool and tool node + tools=get_tools() + tool_node=create_tool_node(tools) + + ## Define the LLM + llm=self.llm + + ## Define the chatbot node + + obj_chatbot_with_node=ChatbotWithToolNode(llm) + chatbot_node=obj_chatbot_with_node.create_chatbot(tools) + + + ## Add nodes + self.graph_builder.add_node("chatbot", chatbot_node) + self.graph_builder.add_node("tools",tool_node) + # Define conditional and direct edges + self.graph_builder.add_edge(START,"chatbot") + self.graph_builder.add_conditional_edges("chatbot",tools_condition) + self.graph_builder.add_edge("tools","chatbot") + # self.graph_builder.add_edge("chatbot",END) + + def research_assistant_build_graph(self): + """ + Builds a research assistant graph with ArXiv and web search tools. + This method creates a chatbot graph specifically designed for academic + research, integrating ArXiv search capabilities alongside web search + to provide comprehensive research assistance. + """ + ## Define the research tools (ArXiv + Web search) + tools = get_tools_by_usecase("Research Assistant") + tool_node = create_tool_node(tools) + + ## Define the LLM + llm = self.llm + + ## Define the chatbot node with research capabilities + obj_chatbot_with_node = ChatbotWithToolNode(llm) + chatbot_node = obj_chatbot_with_node.create_chatbot(tools) + + ## Add nodes + self.graph_builder.add_node("chatbot", chatbot_node) + self.graph_builder.add_node("tools", tool_node) + + # Define conditional and direct edges + self.graph_builder.add_edge(START, "chatbot") + self.graph_builder.add_conditional_edges("chatbot", tools_condition) + self.graph_builder.add_edge("tools", "chatbot") + + + def ai_news_builder_graph(self): + + ai_news_node=AINewsNode(self.llm) + + ## added the nodes + + self.graph_builder.add_node("fetch_news",ai_news_node.fetch_news) + self.graph_builder.add_node("summarize_news",ai_news_node.summarize_news) + self.graph_builder.add_node("save_result",ai_news_node.save_result) + + #added the edges + + self.graph_builder.set_entry_point("fetch_news") + self.graph_builder.add_edge("fetch_news","summarize_news") + self.graph_builder.add_edge("summarize_news","save_result") + self.graph_builder.add_edge("save_result", END) + + def setup_graph(self, usecase: str): + """ + Sets up the graph for the selected use case. + """ + if usecase == "Basic Chatbot": + self.basic_chatbot_build_graph() + elif usecase == "Chatbot with Web Search": + self.chatbot_with_tools_build_graph() + elif usecase == "Research Assistant": + self.research_assistant_build_graph() + elif usecase == "AI News": + self.ai_news_builder_graph() + else: + # Default to basic chatbot if usecase is not recognized + self.basic_chatbot_build_graph() + + return self.graph_builder.compile() \ No newline at end of file diff --git a/src/langgraphagenticai/main.py b/src/langgraphagenticai/main.py new file mode 100644 index 0000000000000000000000000000000000000000..46d9f3118e63dc8c4ba68ff51712fda19aa65811 --- /dev/null +++ b/src/langgraphagenticai/main.py @@ -0,0 +1,60 @@ +import streamlit as st +from src.langgraphagenticai.ui.streamlitui.loadui4 import LoadStreamlitUI +from src.langgraphagenticai.LLMS.groqllm import GroqLLM +from src.langgraphagenticai.graph.graph_builder import GraphBuilder +from src.langgraphagenticai.ui.streamlitui.display_result import DisplayResultStreamlit + +def load_langgraph_agenticai_app(): + """ + This function launches and manages the LangGraph AgenticAI application with a Streamlit user interface. + It initializes the UI, collects user input, configures the selected LLM model, + and sets up the agentic graph workflow based on the chosen use case. Throughout execution, + it displays results interactively and incorporates robust exception handling to ensure reliability and a smooth user experience. + + """ + + ##Load UI + ui=LoadStreamlitUI() + user_input=ui.load_streamlit_ui() + + if not user_input: + st.error("Error: Failed to load user input from the UI.") + return + + # Text input for user message + if st.session_state.IsFetchButtonClicked: + user_message = st.session_state.timeframe + else : + user_message = st.chat_input("Enter your message:") + + if user_message: + try: + ## Configure The LLM's + obj_llm_config=GroqLLM(user_contols_input=user_input) + model=obj_llm_config.get_llm_model() + + if not model: + st.error("Error: LLM model could not be initialized") + return + + # Initialize and set up the graph based on use case + usecase=user_input.get("selected_usecase") + + if not usecase: + st.error("Error: No use case selected.") + return + + ## Graph Builder + + graph_builder=GraphBuilder(model) + try: + graph=graph_builder.setup_graph(usecase) + print(user_message) + DisplayResultStreamlit(usecase,graph,user_message).display_result_on_ui() + except Exception as e: + st.error(f"Error: Graph set up failed- {e}") + return + + except Exception as e: + st.error(f"Error: Graph set up failed- {e}") + return diff --git a/src/langgraphagenticai/nodes/__init__.py b/src/langgraphagenticai/nodes/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/langgraphagenticai/nodes/__pycache__/__init__.cpython-313.pyc b/src/langgraphagenticai/nodes/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f6f5cdec2c05b184da7477b808512be5a2859c0 Binary files /dev/null and b/src/langgraphagenticai/nodes/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/langgraphagenticai/nodes/__pycache__/ai_news_node.cpython-313.pyc b/src/langgraphagenticai/nodes/__pycache__/ai_news_node.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55ebfc39a44437a4cd6b2173991660bda1cd6f62 Binary files /dev/null and b/src/langgraphagenticai/nodes/__pycache__/ai_news_node.cpython-313.pyc differ diff --git a/src/langgraphagenticai/nodes/__pycache__/basic_chatbot_node.cpython-313.pyc b/src/langgraphagenticai/nodes/__pycache__/basic_chatbot_node.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97cbec94b20f1d99bf260a875533e3f0ce9e19dc Binary files /dev/null and b/src/langgraphagenticai/nodes/__pycache__/basic_chatbot_node.cpython-313.pyc differ diff --git a/src/langgraphagenticai/nodes/__pycache__/chatbot_with_Tool_node.cpython-313.pyc b/src/langgraphagenticai/nodes/__pycache__/chatbot_with_Tool_node.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..937a0543a050f4737383efc4e4e5bf543b27f6e3 Binary files /dev/null and b/src/langgraphagenticai/nodes/__pycache__/chatbot_with_Tool_node.cpython-313.pyc differ diff --git a/src/langgraphagenticai/nodes/ai_news_node.py b/src/langgraphagenticai/nodes/ai_news_node.py new file mode 100644 index 0000000000000000000000000000000000000000..fa57cd31c0f41f137ac19c1ae4f05d5d35108d3d --- /dev/null +++ b/src/langgraphagenticai/nodes/ai_news_node.py @@ -0,0 +1,89 @@ +from tavily import TavilyClient +from langchain_core.prompts import ChatPromptTemplate + + +class AINewsNode: + def __init__(self,llm): + """ + Initialize the AINewsNode with API keys for Tavily and GROQ. + """ + self.tavily = TavilyClient() + self.llm = llm + # this is used to capture various steps in this file so that later can be use for steps shown + self.state = {} + + def fetch_news(self, state: dict) -> dict: + """ + Fetch AI news based on the specified frequency. + + Args: + state (dict): The state dictionary containing 'frequency'. + + Returns: + dict: Updated state with 'news_data' key containing fetched news. + """ + + frequency = state['messages'][0].content.lower() + self.state['frequency'] = frequency + time_range_map = {'daily': 'd', 'weekly': 'w', 'monthly': 'm', 'year': 'y'} + days_map = {'daily': 1, 'weekly': 7, 'monthly': 30, 'year': 366} + + response = self.tavily.search( + query="Top Artificial Intelligence (AI) technology news globally", + topic="news", + time_range=time_range_map[frequency], + include_answer="advanced", + max_results=20, + days=days_map[frequency], + # include_domains=["techcrunch.com", "venturebeat.com/ai", ...] # Uncomment and add domains if needed + ) + + state['news_data'] = response.get('results', []) + self.state['news_data'] = state['news_data'] + return state + + + def summarize_news(self, state: dict) -> dict: + """ + Summarize the fetched news using an LLM. + + Args: + state (dict): The state dictionary containing 'news_data'. + + Returns: + dict: Updated state with 'summary' key containing the summarized news. + """ + + news_items = self.state['news_data'] + + prompt_template = ChatPromptTemplate.from_messages([ + ("system", """Summarize AI news articles into markdown format. For each item include: + - Date in **YYYY-MM-DD** format in IST timezone + - Concise sentences summary from latest news + - Sort news by date wise (latest first) + - Source URL as link + Use format: + ### [Date] + - [Summary](URL)"""), + ("user", "Articles:\n{articles}") + ]) + + articles_str = "\n\n".join([ + f"Content: {item.get('content', '')}\nURL: {item.get('url', '')}\nDate: {item.get('published_date', '')}" + for item in news_items + ]) + + response = self.llm.invoke(prompt_template.format(articles=articles_str)) + state['summary'] = response.content + self.state['summary'] = state['summary'] + return self.state + + def save_result(self,state): + frequency = self.state['frequency'] + summary = self.state['summary'] + filename = f"./AINews/{frequency}_summary.md" + with open(filename, 'w') as f: + f.write(f"# {frequency.capitalize()} AI News Summary\n\n") + f.write(summary) + self.state['filename'] = filename + return self.state \ No newline at end of file diff --git a/src/langgraphagenticai/nodes/basic_chatbot_node.py b/src/langgraphagenticai/nodes/basic_chatbot_node.py new file mode 100644 index 0000000000000000000000000000000000000000..6808356ebff20865239ca2c63454522fe4be4379 --- /dev/null +++ b/src/langgraphagenticai/nodes/basic_chatbot_node.py @@ -0,0 +1,14 @@ +from src.langgraphagenticai.state.state import State + +class BasicChatbotNode: + """ + Basic Chatbot login implementation + """ + def __init__(self,model): + self.llm=model + + def process(self,state:State)->dict: + """ + Processes the input state and generates a chatbot response. + """ + return {"messages":self.llm.invoke(state['messages'])} \ No newline at end of file diff --git a/src/langgraphagenticai/nodes/chatbot_with_Tool_node.py b/src/langgraphagenticai/nodes/chatbot_with_Tool_node.py new file mode 100644 index 0000000000000000000000000000000000000000..2959d44dc793a1c125e7d64d859652a5c123f1b7 --- /dev/null +++ b/src/langgraphagenticai/nodes/chatbot_with_Tool_node.py @@ -0,0 +1,35 @@ +from src.langgraphagenticai.state.state import State + +class ChatbotWithToolNode: + """ + Chatbot logic enhanced with tool integration. + """ + def __init__(self,model): + self.llm = model + + def process(self, state: State) -> dict: + """ + Processes the input state and generates a response with tool integration. + """ + user_input = state["messages"][-1] if state["messages"] else "" + llm_response = self.llm.invoke([{"role": "user", "content": user_input}]) + + # Simulate tool-specific logic + tools_response = f"Tool integration for: '{user_input}'" + + return {"messages": [llm_response, tools_response]} + + + def create_chatbot(self, tools): + """ + Returns a chatbot node function. + """ + llm_with_tools = self.llm.bind_tools(tools) + + def chatbot_node(state: State): + """ + Chatbot logic for processing the input state and returning a response. + """ + return {"messages": [llm_with_tools.invoke(state["messages"])]} + + return chatbot_node diff --git a/src/langgraphagenticai/state/__init__.py b/src/langgraphagenticai/state/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/langgraphagenticai/state/__pycache__/__init__.cpython-313.pyc b/src/langgraphagenticai/state/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e82fe4c0f36ccb2b6904f39c0a707f76cde31972 Binary files /dev/null and b/src/langgraphagenticai/state/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/langgraphagenticai/state/__pycache__/state.cpython-313.pyc b/src/langgraphagenticai/state/__pycache__/state.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65bac8fa71e3b8474b9edc30d5f0c710a51857f9 Binary files /dev/null and b/src/langgraphagenticai/state/__pycache__/state.cpython-313.pyc differ diff --git a/src/langgraphagenticai/state/state.py b/src/langgraphagenticai/state/state.py new file mode 100644 index 0000000000000000000000000000000000000000..f4b486c53e0b5c7d742ff84cfad666da1c141995 --- /dev/null +++ b/src/langgraphagenticai/state/state.py @@ -0,0 +1,10 @@ +from typing_extensions import TypedDict,List +from langgraph.graph.message import add_messages +from typing import Annotated + + +class State(TypedDict): + """ + Represent the structure of the state used in graph + """ + messages: Annotated[List,add_messages] \ No newline at end of file diff --git a/src/langgraphagenticai/tools/__init__.py b/src/langgraphagenticai/tools/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/langgraphagenticai/tools/__pycache__/__init__.cpython-313.pyc b/src/langgraphagenticai/tools/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4ecbc0fb75a68f00011a1b8eee3bb377de99744 Binary files /dev/null and b/src/langgraphagenticai/tools/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/langgraphagenticai/tools/__pycache__/arxiv_tool.cpython-313.pyc b/src/langgraphagenticai/tools/__pycache__/arxiv_tool.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c95530a759aba3955d2931eeb9b24f7ce86a07f2 Binary files /dev/null and b/src/langgraphagenticai/tools/__pycache__/arxiv_tool.cpython-313.pyc differ diff --git a/src/langgraphagenticai/tools/__pycache__/search_tool.cpython-313.pyc b/src/langgraphagenticai/tools/__pycache__/search_tool.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3adfc8b8c99fe3157c0dea275c2168084048d4c9 Binary files /dev/null and b/src/langgraphagenticai/tools/__pycache__/search_tool.cpython-313.pyc differ diff --git a/src/langgraphagenticai/tools/arxiv_tool.py b/src/langgraphagenticai/tools/arxiv_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..8bc2caa18d003503d72d592ccd020f9cde67ec2e --- /dev/null +++ b/src/langgraphagenticai/tools/arxiv_tool.py @@ -0,0 +1,42 @@ +from langchain_community.tools import ArxivQueryRun +from langchain_community.utilities import ArxivAPIWrapper +from langgraph.prebuilt import ToolNode + +def get_arxiv_tools(): + """ + Return the list of ArXiv tools for research assistance + """ + # Initialize ArXiv API wrapper with configuration + arxiv_wrapper = ArxivAPIWrapper( + top_k_results=5, # Return top 5 most relevant papers + doc_content_chars_max=5000 # Limit content to 5000 characters per paper + ) + + # Create ArXiv query tool + arxiv_tool = ArxivQueryRun(api_wrapper=arxiv_wrapper) + + tools = [arxiv_tool] + return tools + +def create_arxiv_tool_node(tools): + """ + Creates and returns a tool node for ArXiv research tools + """ + return ToolNode(tools=tools) + +def get_research_assistant_tools(): + """ + Return combined tools for research assistant (ArXiv + web search if needed) + """ + from .search_tool import get_tools as get_web_tools + + # Get ArXiv tools + arxiv_tools = get_arxiv_tools() + + # Get web search tools + web_tools = get_web_tools() + + # Combine both tool sets for comprehensive research + combined_tools = arxiv_tools + web_tools + + return combined_tools \ No newline at end of file diff --git a/src/langgraphagenticai/tools/search_tool.py b/src/langgraphagenticai/tools/search_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..4bd14d2cbb6e54dd59d8925c1f1a08391b0bec5f --- /dev/null +++ b/src/langgraphagenticai/tools/search_tool.py @@ -0,0 +1,28 @@ +from langchain_community.tools.tavily_search import TavilySearchResults +from langgraph.prebuilt import ToolNode + +def get_tools(): + """ + Return the list of tools to be used in the chatbot + """ + tools=[TavilySearchResults(max_results=2)] + return tools + +def create_tool_node(tools): + """ + creates and returns a tool node for the graph + """ + return ToolNode(tools=tools) + +def get_tools_by_usecase(usecase): + """ + Return tools based on the specific use case + """ + if usecase == "Chatbot with Web Search": + return get_tools() + elif usecase == "Research Assistant": + from .arxiv_tool import get_research_assistant_tools + return get_research_assistant_tools() + else: + # Default to web search tools + return get_tools() \ No newline at end of file diff --git a/src/langgraphagenticai/ui/__init__.py b/src/langgraphagenticai/ui/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/langgraphagenticai/ui/__pycache__/__init__.cpython-311.pyc b/src/langgraphagenticai/ui/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2e6ac6e3bfad67c36d28f4932bc7d090dfa11a3 Binary files /dev/null and b/src/langgraphagenticai/ui/__pycache__/__init__.cpython-311.pyc differ diff --git a/src/langgraphagenticai/ui/__pycache__/__init__.cpython-313.pyc b/src/langgraphagenticai/ui/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e8fa1f3cadd2d24cc2b8dcec994ebf36e624d19 Binary files /dev/null and b/src/langgraphagenticai/ui/__pycache__/__init__.cpython-313.pyc differ diff --git a/src/langgraphagenticai/ui/__pycache__/uiconfigfile.cpython-311.pyc b/src/langgraphagenticai/ui/__pycache__/uiconfigfile.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1953d95febd7d39a9c27777614ff5660d5449889 Binary files /dev/null and b/src/langgraphagenticai/ui/__pycache__/uiconfigfile.cpython-311.pyc differ diff --git a/src/langgraphagenticai/ui/__pycache__/uiconfigfile.cpython-313.pyc b/src/langgraphagenticai/ui/__pycache__/uiconfigfile.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71f80cb8fcd2eea6240d1504de2c73f09566bc03 Binary files /dev/null and b/src/langgraphagenticai/ui/__pycache__/uiconfigfile.cpython-313.pyc differ diff --git a/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-313.pyc b/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..daa7e2dc9ccf0ec8186320a0822e6c75a7cdbfd8 Binary files /dev/null and b/src/langgraphagenticai/ui/streamlitui/__pycache__/display_result.cpython-313.pyc differ diff --git a/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui.cpython-313.pyc b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f673b495f871352ef793361efc83be851ad159cc Binary files /dev/null and b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui.cpython-313.pyc differ diff --git a/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui2.cpython-311.pyc b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui2.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3cdebb36900f66740f1cf87c4a2c484dbe3cc8c1 Binary files /dev/null and b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui2.cpython-311.pyc differ diff --git a/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui2.cpython-313.pyc b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui2.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a2c22ab61cce7da1d77936d2893aa65543ba26b Binary files /dev/null and b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui2.cpython-313.pyc differ diff --git a/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui3.cpython-313.pyc b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui3.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75143dca0110752f110e05a3ffa3f578d55ea3b6 Binary files /dev/null and b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui3.cpython-313.pyc differ diff --git a/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui4.cpython-313.pyc b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui4.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dfb93a419f224d72c4be9d53a8a0752f13311fc9 Binary files /dev/null and b/src/langgraphagenticai/ui/streamlitui/__pycache__/loadui4.cpython-313.pyc differ diff --git a/src/langgraphagenticai/ui/streamlitui/display_result.py b/src/langgraphagenticai/ui/streamlitui/display_result.py new file mode 100644 index 0000000000000000000000000000000000000000..94accb7b04564f98456286254c71ec26327e7eb2 --- /dev/null +++ b/src/langgraphagenticai/ui/streamlitui/display_result.py @@ -0,0 +1,82 @@ +import streamlit as st +from langchain_core.messages import HumanMessage,AIMessage,ToolMessage +import json + + +class DisplayResultStreamlit: + def __init__(self,usecase,graph,user_message): + self.usecase= usecase + self.graph = graph + self.user_message = user_message + + def display_result_on_ui(self): + usecase= self.usecase + graph = self.graph + user_message = self.user_message + print(user_message) + if usecase =="Basic Chatbot": + for event in graph.stream({'messages':("user",user_message)}): + print(event.values()) + for value in event.values(): + print(value['messages']) + with st.chat_message("user"): + st.write(user_message) + with st.chat_message("assistant"): + st.write(value["messages"].content) + + elif usecase=="Chatbot with Web Search": + # Prepare state and invoke the graph + initial_state = {"messages": [user_message]} + res = graph.invoke(initial_state) + for message in res['messages']: + if type(message) == HumanMessage: + with st.chat_message("user"): + st.write(message.content) + elif type(message)==ToolMessage: + with st.chat_message("ai"): + st.write("Tool Call Start") + st.write(message.content) + st.write("Tool Call End") + elif type(message)==AIMessage and message.content: + with st.chat_message("assistant"): + st.write(message.content) + + elif usecase=="Research Assistant": + # Prepare state and invoke the graph for research assistance + initial_state = {"messages": [user_message]} + res = graph.invoke(initial_state) + for message in res['messages']: + if type(message) == HumanMessage: + with st.chat_message("user"): + st.write(message.content) + elif type(message)==ToolMessage: + with st.chat_message("ai"): + # Enhanced display for research results + if "arxiv" in message.name.lower(): + st.write("🔬 **ArXiv Research Results:**") + else: + st.write("🌐 **Web Search Results:**") + + # Display the tool result content + st.write(message.content) + st.write("---") + elif type(message)==AIMessage and message.content: + with st.chat_message("assistant"): + st.write(message.content) + + elif usecase == "AI News": + frequency = self.user_message + with st.spinner("Fetching and summarizing news... ⏳"): + result = graph.invoke({"messages": frequency}) + try: + # Read the markdown file + AI_NEWS_PATH = f"./AINews/{frequency.lower()}_summary.md" + with open(AI_NEWS_PATH, "r") as file: + markdown_content = file.read() + + # Display the markdown content in Streamlit + st.markdown(markdown_content, unsafe_allow_html=True) + except FileNotFoundError: + st.error(f"News Not Generated or File not found: {AI_NEWS_PATH}") + except Exception as e: + st.error(f"An error occurred: {str(e)}") \ No newline at end of file diff --git a/src/langgraphagenticai/ui/streamlitui/loadui.py b/src/langgraphagenticai/ui/streamlitui/loadui.py new file mode 100644 index 0000000000000000000000000000000000000000..da94215ca4fceaecc2acb555d86ab876dcc08871 --- /dev/null +++ b/src/langgraphagenticai/ui/streamlitui/loadui.py @@ -0,0 +1,36 @@ +import streamlit as st +import os + +from src.langgraphagenticai.ui.uiconfigfile import Config + +class LoadStreamlitUI: + def __init__(self): + self.config=Config() + self.user_controls={} + + def load_streamlit_ui(self): + st.set_page_config(page_title= "🤖 " + self.config.get_page_title(), layout="wide") + st.header("🤖 " + self.config.get_page_title()) + + + with st.sidebar: + # Get options from config + llm_options = self.config.get_llm_options() + usecase_options = self.config.get_usecase_options() + + # LLM selection + self.user_controls["selected_llm"] = st.selectbox("Select LLM", llm_options) + + if self.user_controls["selected_llm"] == 'Groq': + # Model selection + model_options = self.config.get_groq_model_options() + self.user_controls["selected_groq_model"] = st.selectbox("Select Model", model_options) + self.user_controls["GROQ_API_KEY"] = st.session_state["GROQ_API_KEY"]=st.text_input("API Key",type="password") + # Validate API key + if not self.user_controls["GROQ_API_KEY"]: + st.warning("⚠️ Please enter your GROQ API key to proceed. Don't have? refer : https://console.groq.com/keys ") + + ## USecase selection + self.user_controls["selected_usecase"]=st.selectbox("Select Usecases",usecase_options) + + return self.user_controls \ No newline at end of file diff --git a/src/langgraphagenticai/ui/streamlitui/loadui2.py b/src/langgraphagenticai/ui/streamlitui/loadui2.py new file mode 100644 index 0000000000000000000000000000000000000000..852117644456848713ec11a1c28ec23511107b08 --- /dev/null +++ b/src/langgraphagenticai/ui/streamlitui/loadui2.py @@ -0,0 +1,149 @@ +import streamlit as st +from typing import Dict, Any +from src.langgraphagenticai.ui.uiconfigfile import Config + + +class LoadStreamlitUI: + def __init__(self): + self.config = Config() + self.user_controls: Dict[str, Any] = {} + + def _inject_css(self): + st.markdown( + """ + + """, + unsafe_allow_html=True, + ) + + def load_streamlit_ui(self): + st.set_page_config( + page_title=f"🤖 {self.config.get_page_title()}", + layout="wide", + page_icon="🤖", + ) + self._inject_css() + + # ---- Header (beautiful, minimal) ---- + st.markdown( + f""" +
Selections apply instantly. No extra sections or tabs.
', unsafe_allow_html=True) + st.markdown('✨ Built by Sachin Ranasing
+