fdaudens HF Staff commited on
Commit
d8debf8
·
verified ·
1 Parent(s): d8ef918

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -15
app.py CHANGED
@@ -2,6 +2,20 @@
2
  import os
3
  import logging
4
  import asyncio
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  from llama_index.core.memory import ChatMemoryBuffer
6
  from llama_index.readers.web import RssReader
7
 
@@ -15,6 +29,7 @@ nest_asyncio.apply()
15
  instrumentor = LlamaIndexInstrumentor(
16
  public_key=os.environ.get("LANGFUSE_PUBLIC_KEY"),
17
  secret_key=os.environ.get("LANGFUSE_SECRET_KEY"),
 
18
  )
19
  instrumentor.start()
20
 
@@ -51,7 +66,6 @@ search_tool = FunctionTool.from_defaults(duck_spec.duckduckgo_full_search)
51
  # Weather
52
  openweather_api_key=OPENWEATHERMAP_KEY
53
  weather_tool_spec = OpenWeatherMapToolSpec(key=openweather_api_key)
54
- weather_tool_spec = OpenWeatherMapToolSpec(key=openweather_api_key)
55
  weather_tool = FunctionTool.from_defaults(
56
  weather_tool_spec.weather_at_location,
57
  name="current_weather",
@@ -67,10 +81,6 @@ forecast_tool = FunctionTool.from_defaults(
67
  async def _start_browser():
68
  return await PlaywrightToolSpec.create_async_playwright_browser(headless=True)
69
  browser = asyncio.get_event_loop().run_until_complete(_start_browser())
70
-
71
-
72
-
73
-
74
  playwright_tool_spec = PlaywrightToolSpec.from_async_browser(browser)
75
 
76
  navigate_tool = FunctionTool.from_defaults(
@@ -93,10 +103,6 @@ extract_links_tool = FunctionTool.from_defaults(
93
  def fetch_google_news_rss():
94
  docs = RssReader(html_to_text=True).load_data(["https://news.google.com/rss"])
95
  return [{"title":d.metadata.get("title",""), "url":d.metadata.get("link","")} for d in docs]
96
-
97
-
98
-
99
-
100
  google_rss_tool = FunctionTool.from_defaults(
101
  fn=fetch_google_news_rss,
102
  name="fetch_google_news_rss",
@@ -107,6 +113,13 @@ google_rss_tool = FunctionTool.from_defaults(
107
  async def fetch_serper_news(query: str):
108
  if not serper_api_key:
109
  raise ValueError("Missing SERPER_API_KEY environment variable")
 
 
 
 
 
 
 
110
  serper_news_tool = FunctionTool.from_defaults(
111
  fetch_serper_news,
112
  name="fetch_news_from_serper",
@@ -119,14 +132,41 @@ tools = [
119
  navigate_tool,
120
  extract_text_tool,
121
  extract_links_tool,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  # Gradio interface function
124
  async def gradio_query(user_input, chat_history=None):
125
- chat_history = chat_history or []
 
126
  result = await run_query(user_input)
127
- response = result.response
128
- chat_history.append((user_input, response))
129
- return chat_history, chat_history
130
 
131
  # Build and launch Gradio app
132
  grb = gr.Blocks()
@@ -138,9 +178,13 @@ with grb:
138
  "🙌 Got ideas or improvements? PRs welcome! \n\n"
139
  "👉 _Try asking “What’s the weather in Montreal?” or “What’s in the news today?”_"
140
  )
141
- chatbot = gr.Chatbot() # conversation UI
142
  txt = gr.Textbox(placeholder="Ask me anything...", show_label=False)
143
- txt.submit(gradio_query, [txt, chatbot], [chatbot, chatbot])
 
 
 
 
144
  gr.Button("Send").click(gradio_query, [txt, chatbot], [chatbot, chatbot])
145
 
146
  if __name__ == "__main__":
 
2
  import os
3
  import logging
4
  import asyncio
5
+ import nest_asyncio
6
+ from datetime import datetime
7
+ import uuid
8
+ import aiohttp
9
+ import gradio as gr
10
+
11
+ from langfuse.llama_index import LlamaIndexInstrumentor
12
+ from llama_index.tools.duckduckgo import DuckDuckGoSearchToolSpec
13
+ from llama_index.tools.weather import OpenWeatherMapToolSpec
14
+ from llama_index.tools.playwright import PlaywrightToolSpec
15
+ from llama_index.core.tools import FunctionTool
16
+ from llama_index.core.agent.workflow import AgentWorkflow
17
+ from llama_index.core.workflow import Context
18
+ from llama_index.llms.huggingface_api import HuggingFaceInferenceAPI
19
  from llama_index.core.memory import ChatMemoryBuffer
20
  from llama_index.readers.web import RssReader
21
 
 
29
  instrumentor = LlamaIndexInstrumentor(
30
  public_key=os.environ.get("LANGFUSE_PUBLIC_KEY"),
31
  secret_key=os.environ.get("LANGFUSE_SECRET_KEY"),
32
+ host=os.environ.get("LANGFUSE_HOST"),
33
  )
34
  instrumentor.start()
35
 
 
66
  # Weather
67
  openweather_api_key=OPENWEATHERMAP_KEY
68
  weather_tool_spec = OpenWeatherMapToolSpec(key=openweather_api_key)
 
69
  weather_tool = FunctionTool.from_defaults(
70
  weather_tool_spec.weather_at_location,
71
  name="current_weather",
 
81
  async def _start_browser():
82
  return await PlaywrightToolSpec.create_async_playwright_browser(headless=True)
83
  browser = asyncio.get_event_loop().run_until_complete(_start_browser())
 
 
 
 
84
  playwright_tool_spec = PlaywrightToolSpec.from_async_browser(browser)
85
 
86
  navigate_tool = FunctionTool.from_defaults(
 
103
  def fetch_google_news_rss():
104
  docs = RssReader(html_to_text=True).load_data(["https://news.google.com/rss"])
105
  return [{"title":d.metadata.get("title",""), "url":d.metadata.get("link","")} for d in docs]
 
 
 
 
106
  google_rss_tool = FunctionTool.from_defaults(
107
  fn=fetch_google_news_rss,
108
  name="fetch_google_news_rss",
 
113
  async def fetch_serper_news(query: str):
114
  if not serper_api_key:
115
  raise ValueError("Missing SERPER_API_KEY environment variable")
116
+ url = f"https://google.serper.dev/news?q={query}&tbs=qdr%3Ad"
117
+ headers = {"X-API-KEY": serper_api_key, "Content-Type": "application/json"}
118
+ async with aiohttp.ClientSession() as session:
119
+ async with session.get(url, headers=headers) as resp:
120
+ resp.raise_for_status()
121
+ return await resp.json()
122
+
123
  serper_news_tool = FunctionTool.from_defaults(
124
  fetch_serper_news,
125
  name="fetch_news_from_serper",
 
132
  navigate_tool,
133
  extract_text_tool,
134
  extract_links_tool,
135
+ weather_tool,
136
+ forecast_tool,
137
+ google_rss_tool,
138
+ serper_news_tool,
139
+ ]
140
+ web_agent = AgentWorkflow.from_tools_or_functions(tools, llm=llm)
141
+ ctx = Context(web_agent)
142
+
143
+ # Async helper to run agent queries
144
+ def run_query_sync(query: str):
145
+ """Helper to run async agent.run in sync context."""
146
+ return asyncio.get_event_loop().run_until_complete(
147
+ web_agent.run(query, ctx=ctx)
148
+ )
149
+
150
+ async def run_query(query: str):
151
+ trace_id = f"agent-run-{uuid.uuid4().hex}"
152
+ try:
153
+ with instrumentor.observe(
154
+ trace_id=trace_id,
155
+ session_id="web-agent-session",
156
+ user_id=ANON_USER_ID,
157
+ ):
158
+ return await web_agent.run(query, ctx=ctx)
159
+ finally:
160
+ instrumentor.flush()
161
 
162
  # Gradio interface function
163
  async def gradio_query(user_input, chat_history=None):
164
+ history = chat_history or []
165
+ history.append({"role": "user", "content": user_input})
166
  result = await run_query(user_input)
167
+ text = result.response if isinstance(result.response, str) else str(result.response)
168
+ history.append({"role": "assistant", "content": text})
169
+ return history, history
170
 
171
  # Build and launch Gradio app
172
  grb = gr.Blocks()
 
178
  "🙌 Got ideas or improvements? PRs welcome! \n\n"
179
  "👉 _Try asking “What’s the weather in Montreal?” or “What’s in the news today?”_"
180
  )
181
+ chatbot = gr.Chatbot(type="messages")
182
  txt = gr.Textbox(placeholder="Ask me anything...", show_label=False)
183
+ txt.submit(
184
+ gradio_query,
185
+ inputs=[txt, chatbot],
186
+ outputs=[chatbot, chatbot] # first for display, second for state
187
+ )
188
  gr.Button("Send").click(gradio_query, [txt, chatbot], [chatbot, chatbot])
189
 
190
  if __name__ == "__main__":