lmrkmrcs commited on
Commit
a29de0f
·
verified ·
1 Parent(s): 514eae0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -0
app.py ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ LlamaIndex Agent for HuggingFace AI Agents Course - Unit 2
3
+ Simple ReAct agent using LlamaIndex FunctionTool.
4
+ """
5
+
6
+ import os
7
+ import re
8
+ import gradio as gr
9
+ from llama_index.core.tools import FunctionTool
10
+
11
+ # ============================================
12
+ # TOOLS (using LlamaIndex FunctionTool)
13
+ # ============================================
14
+
15
+ def calculate(operation: str) -> str:
16
+ """Performs basic math calculations. Args: operation - A math expression like '2 + 2'"""
17
+ try:
18
+ allowed = set('0123456789+-*/(). ')
19
+ if all(c in allowed for c in operation):
20
+ return f"Result: {eval(operation)}"
21
+ return "Invalid operation"
22
+ except Exception as e:
23
+ return f"Error: {e}"
24
+
25
+ def get_current_time() -> str:
26
+ """Gets the current date and time in UTC."""
27
+ from datetime import datetime
28
+ return f"Current time (UTC): {datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')}"
29
+
30
+ def get_weather(city: str) -> str:
31
+ """Gets weather for a city (mock data)."""
32
+ import random
33
+ conditions = ["sunny", "cloudy", "rainy", "windy"]
34
+ return f"Weather in {city}: {random.randint(15,30)}°C, {random.choice(conditions)}"
35
+
36
+ def count_words(text: str) -> str:
37
+ """Counts words in text."""
38
+ return f"Word count: {len(text.split())}"
39
+
40
+ # Create LlamaIndex FunctionTools
41
+ calc_tool = FunctionTool.from_defaults(fn=calculate, name="calculate")
42
+ time_tool = FunctionTool.from_defaults(fn=get_current_time, name="get_time")
43
+ weather_tool = FunctionTool.from_defaults(fn=get_weather, name="get_weather")
44
+ words_tool = FunctionTool.from_defaults(fn=count_words, name="count_words")
45
+
46
+ TOOLS = {
47
+ "calculate": calculate,
48
+ "get_time": get_current_time,
49
+ "get_weather": get_weather,
50
+ "count_words": count_words,
51
+ }
52
+
53
+ # ============================================
54
+ # AGENT (Simple ReAct with direct API call)
55
+ # ============================================
56
+
57
+ def call_hf_api(prompt: str) -> str:
58
+ """Call HuggingFace Inference API."""
59
+ import requests
60
+
61
+ token = os.environ.get("HF_TOKEN")
62
+
63
+ # Use the OpenAI-compatible endpoint
64
+ response = requests.post(
65
+ "https://router.huggingface.co/novita/v3/openai/chat/completions",
66
+ headers={
67
+ "Authorization": f"Bearer {token}",
68
+ "Content-Type": "application/json"
69
+ },
70
+ json={
71
+ "model": "meta-llama/llama-3.1-8b-instruct",
72
+ "messages": [{"role": "user", "content": prompt}],
73
+ "max_tokens": 500,
74
+ "temperature": 0.7
75
+ },
76
+ timeout=60
77
+ )
78
+
79
+ if response.status_code == 200:
80
+ return response.json()["choices"][0]["message"]["content"]
81
+ else:
82
+ raise Exception(f"API Error {response.status_code}: {response.text}")
83
+
84
+
85
+ def run_agent(query: str) -> str:
86
+ """Run the ReAct agent loop."""
87
+
88
+ tools_desc = """Available tools:
89
+ - calculate: Do math (e.g., "2+2", "10*5")
90
+ - get_time: Get current UTC time
91
+ - get_weather: Get weather for a city
92
+ - count_words: Count words in text"""
93
+
94
+ prompt = f"""{tools_desc}
95
+
96
+ To use a tool: Action: <name> | Input: <value>
97
+ For final answer: Answer: <response>
98
+
99
+ Query: {query}
100
+ Response:"""
101
+
102
+ for _ in range(3):
103
+ try:
104
+ response = call_hf_api(prompt)
105
+
106
+ # Check for final answer
107
+ if "Answer:" in response:
108
+ return response.split("Answer:")[-1].strip()
109
+
110
+ # Check for tool use
111
+ action = re.search(r"Action:\s*(\w+)", response)
112
+ inp = re.search(r"Input:\s*(.+?)(?:\n|$)", response)
113
+
114
+ if action:
115
+ tool_name = action.group(1).lower()
116
+ tool_input = inp.group(1).strip() if inp else ""
117
+
118
+ # Find and call tool
119
+ for name, func in TOOLS.items():
120
+ if tool_name in name.lower():
121
+ if name == "get_time":
122
+ result = func()
123
+ else:
124
+ result = func(tool_input)
125
+
126
+ prompt += f"\n{response}\nObservation: {result}\nResponse:"
127
+ break
128
+ else:
129
+ return response
130
+ else:
131
+ return response
132
+
133
+ except Exception as e:
134
+ return f"Error: {str(e)}"
135
+
136
+ return "Could not complete request."
137
+
138
+
139
+ # ============================================
140
+ # GRADIO UI
141
+ # ============================================
142
+
143
+ def chat(message, history):
144
+ if not message.strip():
145
+ return "Please ask something!"
146
+ return run_agent(message)
147
+
148
+ with gr.Blocks(title="LlamaIndex Agent") as demo:
149
+ gr.Markdown("""
150
+ # 🦙 LlamaIndex ReAct Agent - Unit 2
151
+
152
+ Built with **LlamaIndex FunctionTool** for the HuggingFace AI Agents Course.
153
+
154
+ **Tools:** Calculator | Time | Weather | Word Count
155
+ ---
156
+ """)
157
+
158
+ gr.ChatInterface(
159
+ fn=chat,
160
+ examples=[
161
+ "What is 25 * 4 + 10?",
162
+ "What time is it?",
163
+ "Weather in Tokyo?",
164
+ "Count words: hello world test",
165
+ ],
166
+ )
167
+
168
+ gr.Markdown("---\n*Unit 2: LlamaIndex Framework*")
169
+
170
+ if __name__ == "__main__":
171
+ demo.launch()