imeesam commited on
Commit
00c776f
Β·
verified Β·
1 Parent(s): 37ed38b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -0
app.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py β€” Entry point for HF Spaces
2
+ import os
3
+ import gradio as gr
4
+ from typing import TypedDict, Annotated
5
+ from langgraph.graph import StateGraph, START, END
6
+ from langgraph.prebuilt import ToolNode, tools_condition
7
+ from langgraph.graph.message import add_messages
8
+ from langchain_core.messages import BaseMessage, HumanMessage, AIMessage
9
+ from langchain_groq import ChatGroq
10
+ from langchain_community.tools import DuckDuckGoSearchRun
11
+ from langchain_core.tools import tool
12
+ import requests
13
+
14
+ os.environ["GROQ_API_KEY"] = os.getenv("GROQ_API_KEY")
15
+
16
+ # ─── LLM ─────────────────────────────────
17
+ llm = ChatGroq(
18
+ model="llama-3.1-8b-instant")
19
+
20
+ # ─── Tools ───────────────────────────────
21
+ search_tool = DuckDuckGoSearchRun()
22
+
23
+ @tool
24
+ def calculator(first_num: float, second_num: float, operation: str) -> dict:
25
+ """Perform basic arithmetic. Operations: add, sub, mul, div"""
26
+ ops = {"add": first_num + second_num, "sub": first_num - second_num,
27
+ "mul": first_num * second_num}
28
+ if operation == "div":
29
+ return {"result": "Division by zero" if second_num == 0 else first_num / second_num}
30
+ return {"result": ops.get(operation, f"Unknown operation: {operation}")}
31
+
32
+ @tool
33
+ def get_stock_price(symbol: str) -> dict:
34
+ """Fetch latest stock price for a symbol like AAPL or TSLA."""
35
+ url = f"https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol={symbol}&apikey={os.getenv('STOCKS_API_KEY')}"
36
+ return requests.get(url).json()
37
+
38
+ tools = [search_tool, calculator, get_stock_price]
39
+ llm_with_tools = llm.bind_tools(tools)
40
+
41
+ # ─── State ───────────────────────────────
42
+ class ChatState(TypedDict):
43
+ messages: Annotated[list[BaseMessage], add_messages]
44
+
45
+ # ─── Graph ───────────────────────────────
46
+ def chat_node(state: ChatState):
47
+ """LLM node that may answer or request a tool call."""
48
+ messages = state['messages']
49
+ response = llm_with_tools.invoke(messages)
50
+ return {"messages": [response]}
51
+
52
+ graph = StateGraph(ChatState)
53
+ graph.add_node("chat_node", chat_node)
54
+ graph.add_node("tools", ToolNode(tools))
55
+ graph.add_edge(START, "chat_node")
56
+ graph.add_conditional_edges("chat_node", tools_condition)
57
+ graph.add_edge("tools", "chat_node")
58
+ agent = graph.compile()
59
+
60
+ # ─── Gradio UI ───────────────────────────
61
+ def respond(message, history):
62
+ # Convert Gradio history β†’ LangChain messages
63
+ messages = []
64
+ for user_msg, bot_msg in history:
65
+ messages.append(HumanMessage(content=user_msg))
66
+ if bot_msg:
67
+ messages.append(AIMessage(content=bot_msg))
68
+ messages.append(HumanMessage(content=message))
69
+
70
+ result = agent.invoke({"messages": messages})
71
+ return result["messages"][-1].content
72
+
73
+ demo = gr.ChatInterface(
74
+ fn=respond,
75
+ title="πŸ” AI Research Agent",
76
+ description="Ask me anything β€” I can search the web and do calculations!",
77
+ examples=[
78
+ "What is LangGraph?",
79
+ "What's happening in AI news today?",
80
+ "Calculate 128 multiplied by 37",
81
+ ],
82
+ theme=gr.themes.Soft()
83
+ )
84
+
85
+ if __name__ == "__main__":
86
+ demo.launch()