genaitiwari commited on
Commit
b213c2c
Β·
1 Parent(s): e8b7d05

ai news completed

Browse files
.gitignore CHANGED
@@ -1,2 +1,4 @@
1
  *.pyc
2
  /.chroma_db
 
 
 
1
  *.pyc
2
  /.chroma_db
3
+ /AINews
4
+ *.ipynb
README.md CHANGED
@@ -173,6 +173,11 @@ To stop the Streamlit app, press `Ctrl+C` in the terminal where the app is runni
173
  ![tp flow](screenshots/tp_flow.png)
174
  ![Travel planner](screenshots/travel_planner.png)
175
 
 
 
 
 
 
176
  ---
177
 
178
  ## πŸ“š Templates & Community
 
173
  ![tp flow](screenshots/tp_flow.png)
174
  ![Travel planner](screenshots/travel_planner.png)
175
 
176
+ ### 6. Travel Planner
177
+ **Reference**:
178
+ ![ai news flow](screenshots/ai_news_flow.png)
179
+ ![ai news](screenshots/ai_news.png)
180
+
181
  ---
182
 
183
  ## πŸ“š Templates & Community
screenshots/ai_news.png ADDED
screenshots/ai_news_flow.png ADDED
src/langgraphagenticai/graph/graph_builder.py CHANGED
@@ -3,6 +3,7 @@ from langgraph.prebuilt import tools_condition,ToolNode
3
  from langchain_core.prompts import ChatPromptTemplate
4
  import datetime
5
  #module import
 
6
  from src.langgraphagenticai.node import travel_planner_node
7
  from src.langgraphagenticai.node.customer_support_chatbot import Customer_Support_Bot
8
  from src.langgraphagenticai.tools.customtool import book_appointment, cancel_appointment, get_next_available_appointment
@@ -80,7 +81,7 @@ class GraphBuilder:
80
  # Define the edge to end the graph after the Travel Planner completes
81
  self.graph_builder.add_edge("travel_planner", END)
82
 
83
- # Helper methods
84
  # Nodes
85
  def call_caller_model(self,state: MessagesState):
86
  state["current_time"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
@@ -95,7 +96,9 @@ class GraphBuilder:
95
  return "end"
96
  else:
97
  return "continue"
98
-
 
 
99
  def appointment_receptionist_bot_build_graph(self):
100
  caller_tools = [book_appointment, get_next_available_appointment, cancel_appointment]
101
  tool_node = ToolNode(caller_tools)
@@ -132,6 +135,19 @@ class GraphBuilder:
132
  def customer_support_build_graph(self):
133
  obj_cs_bot = Customer_Support_Bot(llm=self.llm)
134
  self.graph_builder = obj_cs_bot.chat_bot()
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
  def setup_graph(self, usecase: str):
137
  """
@@ -147,6 +163,8 @@ class GraphBuilder:
147
  self.appointment_receptionist_bot_build_graph()
148
  elif usecase =="Customer Support":
149
  self.customer_support_build_graph()
 
 
150
  else:
151
  raise ValueError("Invalid use case selected.")
152
  return self.graph_builder.compile()
 
3
  from langchain_core.prompts import ChatPromptTemplate
4
  import datetime
5
  #module import
6
+ from src.langgraphagenticai.node.ai_news_node import AINewsNode
7
  from src.langgraphagenticai.node import travel_planner_node
8
  from src.langgraphagenticai.node.customer_support_chatbot import Customer_Support_Bot
9
  from src.langgraphagenticai.tools.customtool import book_appointment, cancel_appointment, get_next_available_appointment
 
81
  # Define the edge to end the graph after the Travel Planner completes
82
  self.graph_builder.add_edge("travel_planner", END)
83
 
84
+ # Helper methods - START
85
  # Nodes
86
  def call_caller_model(self,state: MessagesState):
87
  state["current_time"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
 
96
  return "end"
97
  else:
98
  return "continue"
99
+
100
+
101
+ # Helper method - END
102
  def appointment_receptionist_bot_build_graph(self):
103
  caller_tools = [book_appointment, get_next_available_appointment, cancel_appointment]
104
  tool_node = ToolNode(caller_tools)
 
135
  def customer_support_build_graph(self):
136
  obj_cs_bot = Customer_Support_Bot(llm=self.llm)
137
  self.graph_builder = obj_cs_bot.chat_bot()
138
+
139
+ def ai_news_build_graph(self):
140
+ # Initialize the AINewsNode
141
+ ai_news_node = AINewsNode(self.llm)
142
+
143
+ self.graph_builder.add_node("fetch_news", ai_news_node.fetch_news)
144
+ self.graph_builder.add_node("summarize_news", ai_news_node.summarize_news)
145
+ self.graph_builder.add_node("save_result", ai_news_node.save_result)
146
+
147
+ self.graph_builder.set_entry_point("fetch_news")
148
+ self.graph_builder.add_edge("fetch_news", "summarize_news")
149
+ self.graph_builder.add_edge("summarize_news", "save_result")
150
+ self.graph_builder.add_edge("save_result", END)
151
 
152
  def setup_graph(self, usecase: str):
153
  """
 
163
  self.appointment_receptionist_bot_build_graph()
164
  elif usecase =="Customer Support":
165
  self.customer_support_build_graph()
166
+ elif usecase =="AI News":
167
+ self.ai_news_build_graph()
168
  else:
169
  raise ValueError("Invalid use case selected.")
170
  return self.graph_builder.compile()
src/langgraphagenticai/main.py CHANGED
@@ -26,7 +26,10 @@ def load_langgraph_agenticai_app():
26
  return
27
 
28
  # Text input for user message
29
- user_message = st.chat_input("Enter your message:")
 
 
 
30
  if user_message:
31
  try:
32
  # Configure LLM
 
26
  return
27
 
28
  # Text input for user message
29
+ if st.session_state.IsFetchButtonClicked:
30
+ user_message = st.session_state.timeframe
31
+ else :
32
+ user_message = st.chat_input("Enter your message:")
33
  if user_message:
34
  try:
35
  # Configure LLM
src/langgraphagenticai/node/ai_news_node.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from tavily import TavilyClient
2
+ from langchain_openai import ChatOpenAI
3
+ from langchain_core.prompts import ChatPromptTemplate
4
+
5
+ class AINewsNode:
6
+ def __init__(self,llm):
7
+ """
8
+ Initialize the AINewsNode with API keys for Tavily and OpenAI.
9
+ """
10
+ self.tavily = TavilyClient()
11
+ self.llm = llm
12
+ # this is used to capture various steps in this file so that later can be use for steps shown
13
+ self.state = {}
14
+
15
+ def fetch_news(self, state: dict) -> dict:
16
+ """
17
+ Fetch AI news based on the specified frequency.
18
+
19
+ Args:
20
+ state (dict): The state dictionary containing 'frequency'.
21
+
22
+ Returns:
23
+ dict: Updated state with 'news_data' key containing fetched news.
24
+ """
25
+ frequency = state['messages'][0].content.lower()
26
+ self.state['frequency'] = frequency
27
+ time_range_map = {'daily': 'd', 'weekly': 'w', 'monthly': 'm', 'year': 'y'}
28
+ days_map = {'daily': 1, 'weekly': 7, 'monthly': 30, 'year': 366}
29
+
30
+ response = self.tavily.search(
31
+ query="Top Artificial Intelligence (AI) technology news India and globally",
32
+ topic="news",
33
+ time_range=time_range_map[frequency],
34
+ include_answer="advanced",
35
+ max_results=15,
36
+ days=days_map[frequency],
37
+ # include_domains=["techcrunch.com", "venturebeat.com/ai", ...] # Uncomment and add domains if needed
38
+ )
39
+ state['news_data'] = response.get('results', [])
40
+ self.state['news_data'] = state['news_data']
41
+ return state
42
+
43
+ def summarize_news(self, state: dict) -> dict:
44
+ """
45
+ Summarize the fetched news using an LLM.
46
+
47
+ Args:
48
+ state (dict): The state dictionary containing 'news_data'.
49
+
50
+ Returns:
51
+ dict: Updated state with 'summary' key containing the summarized news.
52
+ """
53
+ news_items = self.state['news_data']
54
+ prompt_template = ChatPromptTemplate.from_messages([
55
+ ("system", """Summarize AI news articles into markdown format. For each item include:
56
+ - Date in **YYYY-MM-DD** format in IST timezone
57
+ - Concise sentences summary from latest news
58
+ - Sort news by date wise (latest first)
59
+ - Source URL as link
60
+ Use format:
61
+ ### [Date]
62
+ - [Summary](URL)"""),
63
+ ("user", "Articles:\n{articles}")
64
+ ])
65
+
66
+ articles_str = "\n\n".join([
67
+ f"Content: {item.get('content', '')}\nURL: {item.get('url', '')}\nDate: {item.get('published_date', '')}"
68
+ for item in news_items
69
+ ])
70
+
71
+ response = self.llm.invoke(prompt_template.format(articles=articles_str))
72
+ state['summary'] = response.content
73
+ self.state['summary'] = state['summary']
74
+ return self.state
75
+
76
+ def save_result(self,state):
77
+ frequency = self.state['frequency']
78
+ summary = self.state['summary']
79
+ filename = f"./AINews/{frequency}_summary.md"
80
+ with open(filename, 'w') as f:
81
+ f.write(f"# {frequency.capitalize()} AI News Summary\n\n")
82
+ f.write(summary)
83
+ self.state['filename'] = filename
84
+ return self.state
src/langgraphagenticai/ui/streamlitui/display_result.py CHANGED
@@ -88,6 +88,32 @@ class DisplayResultStreamlit:
88
  st.title('data protection checks')
89
  st.write(data_protection_checks)
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  # display graph
92
  if graph:
93
  st.write('state graph - workflow')
 
88
  st.title('data protection checks')
89
  st.write(data_protection_checks)
90
 
91
+ elif usecase == "AI News":
92
+ frequency = self.user_message
93
+ result = graph.invoke({"messages": frequency})
94
+ try:
95
+ # Read the markdown file
96
+ AI_NEWS_PATH = f"./AINews/{frequency.lower()}_summary.md"
97
+ with open(AI_NEWS_PATH, "r") as file:
98
+ markdown_content = file.read()
99
+
100
+ # Display the markdown content in Streamlit
101
+ st.markdown(markdown_content, unsafe_allow_html=True)
102
+ except FileNotFoundError:
103
+ st.error(f"News Not Generated or File not found: {AI_NEWS_PATH}")
104
+ except Exception as e:
105
+ st.error(f"An error occurred: {str(e)}")
106
+
107
+
108
+ with open(AI_NEWS_PATH, 'r') as f:
109
+ st.download_button(
110
+ "πŸ’Ύ Download Summary",
111
+ f.read(),
112
+ file_name=AI_NEWS_PATH,
113
+ mime="text/markdown"
114
+ )
115
+ st.success(f"βœ… Summary saved to {AI_NEWS_PATH}")
116
+
117
  # display graph
118
  if graph:
119
  st.write('state graph - workflow')
src/langgraphagenticai/ui/streamlitui/loadui.py CHANGED
@@ -11,9 +11,14 @@ class LoadStreamlitUI:
11
  self.config = Config() # config
12
  self.user_controls = {}
13
 
 
14
  def load_streamlit_ui(self):
15
  st.set_page_config(page_title= "πŸ€– " + self.config.get_page_title(), layout="wide")
16
  st.header("πŸ€– " + self.config.get_page_title())
 
 
 
 
17
 
18
  with st.sidebar:
19
  # Get options from config
@@ -38,7 +43,7 @@ class LoadStreamlitUI:
38
  # Use case selection
39
  self.user_controls["selected_usecase"] = st.selectbox("Select Usecases", usecase_options)
40
 
41
- if self.user_controls["selected_usecase"] =="Chatbot with Tool":
42
  # API key input
43
  os.environ["TAVILY_API_KEY"] = self.user_controls["TAVILY_API_KEY"] = st.session_state["TAVILY_API_KEY"] = st.text_input("TAVILY API KEY",
44
  type="password")
@@ -93,6 +98,21 @@ class LoadStreamlitUI:
93
  "start_date": start_date,
94
  "end_date": end_date,
95
  })
 
 
 
96
 
97
-
 
 
 
 
 
 
 
 
 
 
 
 
98
  return self.user_controls
 
11
  self.config = Config() # config
12
  self.user_controls = {}
13
 
14
+
15
  def load_streamlit_ui(self):
16
  st.set_page_config(page_title= "πŸ€– " + self.config.get_page_title(), layout="wide")
17
  st.header("πŸ€– " + self.config.get_page_title())
18
+ st.session_state.timeframe = ''
19
+ st.session_state.IsFetchButtonClicked = False
20
+
21
+
22
 
23
  with st.sidebar:
24
  # Get options from config
 
43
  # Use case selection
44
  self.user_controls["selected_usecase"] = st.selectbox("Select Usecases", usecase_options)
45
 
46
+ if self.user_controls["selected_usecase"] =="Chatbot with Tool" or self.user_controls["selected_usecase"] =="AI News" :
47
  # API key input
48
  os.environ["TAVILY_API_KEY"] = self.user_controls["TAVILY_API_KEY"] = st.session_state["TAVILY_API_KEY"] = st.text_input("TAVILY API KEY",
49
  type="password")
 
98
  "start_date": start_date,
99
  "end_date": end_date,
100
  })
101
+
102
+ elif self.user_controls['selected_usecase']=="AI News":
103
+ st.subheader("πŸ“° AI News Explorer ")
104
 
105
+ with st.sidebar:
106
+ time_frame = st.selectbox(
107
+ "πŸ“… Select Time Frame",
108
+ ["Daily", "Weekly", "Monthly"],
109
+ index=0
110
+ )
111
+
112
+ if st.button("πŸ” Fetch Latest AI News", use_container_width=True):
113
+ st.session_state.IsFetchButtonClicked = True
114
+ st.session_state.timeframe = time_frame
115
+ else :
116
+ st.session_state.IsFetchButtonClicked = False
117
+
118
  return self.user_controls
src/langgraphagenticai/ui/uiconfigfile.ini CHANGED
@@ -1,6 +1,6 @@
1
  [DEFAULT]
2
  PAGE_TITLE = LangGraph: Build Stateful Agentic AI graph
3
  LLM_OPTIONS = Groq
4
- USECASE_OPTIONS = Basic Chatbot, Chatbot with Tool, Travel Planner, Appointment Receptionist, Customer Support
5
  GROQ_MODEL_OPTIONS = mixtral-8x7b-32768, llama3-8b-8192, llama3-70b-8192, gemma-7b-i
6
 
 
1
  [DEFAULT]
2
  PAGE_TITLE = LangGraph: Build Stateful Agentic AI graph
3
  LLM_OPTIONS = Groq
4
+ USECASE_OPTIONS = Basic Chatbot, Chatbot with Tool, Travel Planner, AI News, Appointment Receptionist, Customer Support
5
  GROQ_MODEL_OPTIONS = mixtral-8x7b-32768, llama3-8b-8192, llama3-70b-8192, gemma-7b-i
6