chrisjcc commited on
Commit
45fe4f1
·
verified ·
1 Parent(s): 462866a

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +254 -0
app.py ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Dog Weight Calculator Agent - Strands Agents Version
3
+
4
+ This is a rewrite of the original Hugging Face OpenAI-based ReAct agent
5
+ using Amazon's Strands Agents SDK. The original implementation used a
6
+ manual ReAct loop with regex parsing. Strands handles all of this
7
+ automatically through its model-driven approach.
8
+
9
+ Original: Manual ReAct loop with OpenAI GPT-4
10
+ New: Strands Agents with native tool calling
11
+ """
12
+
13
+ import os
14
+ import gradio as gr
15
+ from strands import Agent, tool
16
+ from strands.models.openai import OpenAIModel
17
+
18
+ # =============================================================================
19
+ # TOOLS
20
+ # =============================================================================
21
+ # In Strands, tools are simply Python functions decorated with @tool.
22
+ # The framework automatically extracts the function signature, docstring,
23
+ # and type hints to create tool specifications for the LLM.
24
+
25
+ @tool
26
+ def calculate(expression: str) -> str:
27
+ """
28
+ Evaluate a mathematical expression and return the result.
29
+
30
+ Args:
31
+ expression: A mathematical expression to evaluate (e.g., "4 * 7 / 3", "37 + 20")
32
+
33
+ Returns:
34
+ The result of the calculation as a string
35
+ """
36
+ try:
37
+ # Using eval for simple math - in production, consider using a safer parser
38
+ result = eval(expression)
39
+ return str(result)
40
+ except Exception as e:
41
+ return f"Error evaluating expression: {e}"
42
+
43
+
44
+ @tool
45
+ def average_dog_weight(breed: str) -> str:
46
+ """
47
+ Get the average weight of a dog breed.
48
+
49
+ Args:
50
+ breed: The name of the dog breed (e.g., "Border Collie", "Scottish Terrier", "Toy Poodle")
51
+
52
+ Returns:
53
+ A string describing the average weight of the specified breed
54
+ """
55
+ # Normalize the breed name for matching
56
+ breed_lower = breed.lower()
57
+
58
+ if "scottish terrier" in breed_lower:
59
+ return "Scottish Terriers average 20 lbs"
60
+ elif "border collie" in breed_lower:
61
+ return "A Border Collie's average weight is 37 lbs"
62
+ elif "toy poodle" in breed_lower:
63
+ return "A Toy Poodle's average weight is 7 lbs"
64
+ elif "bulldog" in breed_lower:
65
+ return "A Bulldog weighs 51 lbs"
66
+ elif "labrador" in breed_lower:
67
+ return "A Labrador Retriever's average weight is 65 lbs"
68
+ elif "german shepherd" in breed_lower:
69
+ return "A German Shepherd's average weight is 75 lbs"
70
+ elif "golden retriever" in breed_lower:
71
+ return "A Golden Retriever's average weight is 65 lbs"
72
+ elif "beagle" in breed_lower:
73
+ return "A Beagle's average weight is 25 lbs"
74
+ elif "chihuahua" in breed_lower:
75
+ return "A Chihuahua's average weight is 5 lbs"
76
+ elif "great dane" in breed_lower:
77
+ return "A Great Dane's average weight is 140 lbs"
78
+ else:
79
+ return f"I don't have specific data for {breed}. An average dog weighs about 50 lbs"
80
+
81
+
82
+ # =============================================================================
83
+ # SYSTEM PROMPT
84
+ # =============================================================================
85
+ # With Strands, we don't need to specify the ReAct format in the prompt.
86
+ # The framework handles tool selection and execution automatically.
87
+ # We just describe the agent's purpose and behavior.
88
+
89
+ SYSTEM_PROMPT = """
90
+ You are a helpful assistant that specializes in answering questions about dog weights.
91
+ You have access to tools that can:
92
+ 1. Look up the average weight of specific dog breeds
93
+ 2. Perform mathematical calculations
94
+
95
+ When a user asks about dog weights:
96
+ - Use the average_dog_weight tool to look up breed-specific information
97
+ - If they ask about multiple dogs, look up each breed separately
98
+ - Use the calculate tool for any math (like adding weights together)
99
+
100
+ Always provide clear, helpful answers about dog weights.
101
+ """.strip()
102
+
103
+
104
+ # =============================================================================
105
+ # AGENT SETUP
106
+ # =============================================================================
107
+
108
+ def create_agent():
109
+ """
110
+ Create and configure the Strands agent.
111
+
112
+ The agent can use either:
113
+ - OpenAI models (requires OPENAI_API_KEY)
114
+ - Amazon Bedrock models (requires AWS credentials, default)
115
+ """
116
+ # Check for OpenAI API key
117
+ openai_api_key = os.environ.get('OPENAI_API_KEY')
118
+
119
+ if openai_api_key:
120
+ # Use OpenAI if API key is available
121
+ model = OpenAIModel(
122
+ client_args={"api_key": openai_api_key},
123
+ model_id="gpt-4o",
124
+ params={
125
+ "temperature": 0,
126
+ "max_tokens": 1024
127
+ }
128
+ )
129
+ print("Using OpenAI GPT-4o model")
130
+ else:
131
+ # Fall back to Bedrock (default in Strands)
132
+ # Requires AWS credentials to be configured
133
+ model = None # Strands uses Bedrock by default
134
+ print("Using Amazon Bedrock (default)")
135
+
136
+ # Create the agent with our tools
137
+ if model:
138
+ agent = Agent(
139
+ model=model,
140
+ system_prompt=SYSTEM_PROMPT,
141
+ tools=[calculate, average_dog_weight]
142
+ )
143
+ else:
144
+ agent = Agent(
145
+ system_prompt=SYSTEM_PROMPT,
146
+ tools=[calculate, average_dog_weight]
147
+ )
148
+
149
+ return agent
150
+
151
+
152
+ def query(question: str) -> str:
153
+ """
154
+ Process a question using the Strands agent.
155
+
156
+ Unlike the original implementation that required manual loop management
157
+ and regex parsing, Strands handles all of this automatically:
158
+ - Tool selection based on the question
159
+ - Tool execution
160
+ - Multi-step reasoning
161
+ - Response generation
162
+
163
+ Args:
164
+ question: The user's question about dog weights
165
+
166
+ Returns:
167
+ The agent's response
168
+ """
169
+ try:
170
+ # Create a fresh agent for each query
171
+ agent = create_agent()
172
+
173
+ # Invoke the agent - Strands handles the entire agentic loop
174
+ result = agent(question)
175
+
176
+ # Extract the final response
177
+ # The result object contains the full conversation and metrics
178
+ return str(result)
179
+
180
+ except Exception as e:
181
+ return f"Error processing question: {str(e)}"
182
+
183
+
184
+ # =============================================================================
185
+ # GRADIO INTERFACE
186
+ # =============================================================================
187
+
188
+ def process_question(question: str) -> str:
189
+ """Wrapper function for Gradio interface."""
190
+ return query(question)
191
+
192
+
193
+ # Create the Gradio interface
194
+ iface = gr.Interface(
195
+ fn=process_question,
196
+ inputs=gr.Textbox(
197
+ label="Enter your question",
198
+ placeholder="e.g., I have 2 dogs, a border collie and a scottish terrier. What is their combined weight?",
199
+ lines=3
200
+ ),
201
+ outputs=gr.Textbox(label="Answer", lines=5),
202
+ title="🐕 Dog Weight Calculator (Strands Agents)",
203
+ description="""
204
+ Ask about dog weights or perform calculations!
205
+
206
+ **Examples:**
207
+ - How much does a toy poodle weigh?
208
+ - I have 2 dogs, a border collie and a scottish terrier. What is their combined weight?
209
+ - What's heavier, a Great Dane or a German Shepherd?
210
+
211
+ *Powered by Amazon Strands Agents SDK*
212
+ """,
213
+ examples=[
214
+ ["How much does a toy poodle weigh?"],
215
+ ["I have 2 dogs, a border collie and a scottish terrier. What is their combined weight?"],
216
+ ["What's the average weight of a Labrador Retriever?"],
217
+ ["If I have a Chihuahua and a Great Dane, how much do they weigh together?"],
218
+ ],
219
+ theme=gr.themes.Soft()
220
+ )
221
+
222
+
223
+ # =============================================================================
224
+ # DEMO / TESTING
225
+ # =============================================================================
226
+
227
+ def run_demo():
228
+ """Run some demo queries to test the agent."""
229
+ print("\n" + "="*60)
230
+ print("STRANDS AGENTS - DOG WEIGHT CALCULATOR DEMO")
231
+ print("="*60 + "\n")
232
+
233
+ test_questions = [
234
+ "How much does a toy poodle weigh?",
235
+ "I have 2 dogs, a border collie and a scottish terrier. What is their combined weight?",
236
+ ]
237
+
238
+ for question in test_questions:
239
+ print(f"Question: {question}")
240
+ print("-" * 40)
241
+ answer = query(question)
242
+ print(f"Answer: {answer}")
243
+ print("\n")
244
+
245
+
246
+ if __name__ == "__main__":
247
+ import sys
248
+
249
+ if "--demo" in sys.argv:
250
+ # Run demo mode
251
+ run_demo()
252
+ else:
253
+ # Launch Gradio interface
254
+ iface.launch()