dkolarova commited on
Commit
8f51a95
·
verified ·
1 Parent(s): b295bd7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +4 -302
app.py CHANGED
@@ -1,308 +1,10 @@
1
- from typing import Dict, List, Any
2
- from dataclasses import dataclass
3
- from datetime import datetime
4
- import os
5
- import json
6
- import requests
7
-
8
-
9
- @dataclass
10
- class Interaction:
11
- """Record of a single interaction with the agent"""
12
- timestamp: datetime
13
- query: str
14
- plan: Dict[str, Any]
15
-
16
- class Agent:
17
- def __init__(self, model: str = "Qwen/Qwen2.5-Coder-32B-Instruct"):
18
- """Initialize Agent with empty interaction history."""
19
- self.interactions: List[Interaction] = [] # Working memory
20
- self.model = model
21
-
22
- def _query_llm(self, messages):
23
- headers = {
24
- "Content-Type": "application/json"
25
- }
26
- data = {
27
- "model": self.model,
28
- "messages": messages,
29
- "max_tokens": 150
30
- }
31
- response = requests.post("https://api-inference.huggingface.co/v1/chat/completions", headers=headers, data=json.dumps(data))
32
- print("Original response ", response.json())
33
- print("\nOriginal response type", type(response.json()['choices'][0]['message']['content']))
34
- # final_response = response.json()['choices'][0]['message']['content'].strip()
35
- # print("LLM Response ", final_response)
36
 
37
- return response.json()['choices'][0]['message']['content'].strip()
38
-
39
- def create_system_prompt(self) -> str:
40
- """Create the system prompt for the LLM with available tools."""
41
- tools_json = {
42
- "role": "AI Assistant",
43
- "capabilities": [
44
- "Using provided tools to help users when necessary",
45
- "Responding directly without tools for questions that don't require tool usage",
46
- "Planning efficient tool usage sequences",
47
- "If asked by the user, reflecting on the plan and suggesting changes if needed"
48
- ],
49
- "instructions": [
50
- "Use tools only when they are necessary for the task",
51
- "If a query can be answered directly, respond with a simple message instead of using tools",
52
- "When tools are needed, plan their usage efficiently to minimize tool calls",
53
- "If asked by the user, reflect on the plan and suggest changes if needed"
54
- ],
55
- "tools": [
56
- {
57
- "name": "convert_currency",
58
- "description": "Converts currency using latest exchange rates.",
59
- "parameters": {
60
- "amount": {
61
- "type": "float",
62
- "description": "Amount to convert"
63
- },
64
- "from_currency": {
65
- "type": "str",
66
- "description": "Source currency code (e.g., USD)"
67
- },
68
- "to_currency": {
69
- "type": "str",
70
- "description": "Target currency code (e.g., EUR)"
71
- }
72
- }
73
- }
74
- ],
75
- "response_format": {
76
- "type": "json",
77
- "schema": {
78
- "requires_tools": {
79
- "type": "boolean",
80
- "description": "whether tools are needed for this query"
81
- },
82
- "direct_response": {
83
- "type": "string",
84
- "description": "response when no tools are needed",
85
- "optional": True
86
- },
87
- "thought": {
88
- "type": "string",
89
- "description": "reasoning about how to solve the task (when tools are needed)",
90
- "optional": True
91
- },
92
- "plan": {
93
- "type": "array",
94
- "items": {"type": "string"},
95
- "description": "steps to solve the task (when tools are needed)",
96
- "optional": True
97
- },
98
- "tool_calls": {
99
- "type": "array",
100
- "items": {
101
- "type": "object",
102
- "properties": {
103
- "tool": {
104
- "type": "string",
105
- "description": "name of the tool"
106
- },
107
- "args": {
108
- "type": "object",
109
- "description": "parameters for the tool"
110
- }
111
- }
112
- },
113
- "description": "tools to call in sequence (when tools are needed)",
114
- "optional": True
115
- }
116
- },
117
- "examples": [
118
- {
119
- "query": "Convert 100 USD to EUR",
120
- "response": {
121
- "requires_tools": True,
122
- "thought": "I need to use the currency conversion tool to convert USD to EUR",
123
- "plan": [
124
- "Use convert_currency tool to convert 100 USD to EUR",
125
- "Return the conversion result"
126
- ],
127
- "tool_calls": [
128
- {
129
- "tool": "convert_currency",
130
- "args": {
131
- "amount": 100,
132
- "from_currency": "USD",
133
- "to_currency": "EUR"
134
- }
135
- }
136
- ]
137
- }
138
- },
139
- {
140
- "query": "What's 500 Japanese Yen in British Pounds?",
141
- "response": {
142
- "requires_tools": True,
143
- "thought": "I need to convert JPY to GBP using the currency converter",
144
- "plan": [
145
- "Use convert_currency tool to convert 500 JPY to GBP",
146
- "Return the conversion result"
147
- ],
148
- "tool_calls": [
149
- {
150
- "tool": "convert_currency",
151
- "args": {
152
- "amount": 500,
153
- "from_currency": "JPY",
154
- "to_currency": "GBP"
155
- }
156
- }
157
- ]
158
- }
159
- },
160
- {
161
- "query": "What currency does Japan use?",
162
- "response": {
163
- "requires_tools": False,
164
- "direct_response": "Japan uses the Japanese Yen (JPY) as its official currency. This is common knowledge that doesn't require using the currency conversion tool."
165
- }
166
- }
167
- ]
168
- }
169
- }
170
-
171
- return f"""You are an AI assistant that helps users by providing direct answers or using tools when necessary.
172
- Configuration, instructions, and available tools are provided in JSON format below:
173
-
174
- {json.dumps(tools_json, indent=2)}
175
-
176
- Always respond with a JSON object following the response_format schema above.
177
- Remember to use tools only when they are actually needed for the task."""
178
-
179
- def plan(self, user_query: str) -> Dict:
180
- """Use LLM to create a plan and store it in memory."""
181
- messages = [
182
- {"role": "system", "content": self.create_system_prompt()},
183
- {"role": "user", "content": user_query}
184
- ]
185
-
186
- response = self._query_llm(messages=messages)
187
-
188
- try:
189
- plan = json.loads(response)
190
- # Store the interaction immediately after planning
191
- interaction = Interaction(
192
- timestamp=datetime.now(),
193
- query=user_query,
194
- plan=plan
195
- )
196
- self.interactions.append(interaction)
197
- return plan
198
- except json.JSONDecodeError:
199
- raise ValueError("Failed to parse LLM response as JSON")
200
-
201
- def reflect_on_plan(self) -> Dict[str, Any]:
202
- """Reflect on the most recent plan using interaction history."""
203
- if not self.interactions:
204
- return {"reflection": "No plan to reflect on", "requires_changes": False}
205
-
206
- latest_interaction = self.interactions[-1]
207
-
208
- reflection_prompt = {
209
- "task": "reflection",
210
- "context": {
211
- "user_query": latest_interaction.query,
212
- "generated_plan": latest_interaction.plan
213
- },
214
- "instructions": [
215
- "Review the generated plan for potential improvements",
216
- "Consider if the chosen tools are appropriate",
217
- "Verify tool parameters are correct",
218
- "Check if the plan is efficient",
219
- "Determine if tools are actually needed"
220
- ],
221
- "response_format": {
222
- "type": "json",
223
- "schema": {
224
- "requires_changes": {
225
- "type": "boolean",
226
- "description": "whether the plan needs modifications"
227
- },
228
- "reflection": {
229
- "type": "string",
230
- "description": "explanation of what changes are needed or why no changes are needed"
231
- },
232
- "suggestions": {
233
- "type": "array",
234
- "items": {"type": "string"},
235
- "description": "specific suggestions for improvements",
236
- "optional": True
237
- }
238
- }
239
- }
240
- }
241
-
242
- messages = [
243
- {"role": "system", "content": self.create_system_prompt()},
244
- {"role": "user", "content": json.dumps(reflection_prompt, indent=2)}
245
- ]
246
-
247
- response = self._query_llm(messages=messages)
248
-
249
- try:
250
- return json.loads(response)
251
- except json.JSONDecodeError:
252
- return {"reflection": response}
253
-
254
- def execute(self, user_query: str) -> str:
255
- """Execute the full pipeline: plan, reflect, and potentially replan."""
256
- try:
257
- # Create initial plan (this also stores it in memory)
258
- initial_plan = self.plan(user_query)
259
-
260
- # Reflect on the plan using memory
261
- reflection = self.reflect_on_plan()
262
-
263
- # Check if reflection suggests changes
264
- if reflection.get("requires_changes", False):
265
- # Generate new plan based on reflection
266
- messages = [
267
- {"role": "system", "content": self.create_system_prompt()},
268
- {"role": "user", "content": user_query},
269
- {"role": "assistant", "content": json.dumps(initial_plan)},
270
- {"role": "user", "content": f"Please revise the plan based on this feedback: {json.dumps(reflection)}"}
271
- ]
272
-
273
- response = self._query_llm(messages=messages)
274
-
275
- try:
276
- final_plan = json.loads(response)
277
- except json.JSONDecodeError:
278
- final_plan = initial_plan # Fallback to initial plan if parsing fails
279
- else:
280
- final_plan = initial_plan
281
-
282
- # Update the stored interaction with all information
283
- self.interactions[-1].plan = {
284
- "initial_plan": initial_plan,
285
- "reflection": reflection,
286
- "final_plan": final_plan
287
- }
288
-
289
- # Return the appropriate response
290
- if final_plan.get("requires_tools", True):
291
- return f"""Initial Thought: {initial_plan['thought']}
292
- Initial Plan: {'. '.join(initial_plan['plan'])}
293
- Reflection: {reflection.get('reflection', 'No improvements suggested')}
294
- Final Plan: {'. '.join(final_plan['plan'])}"""
295
- else:
296
- return f"""Response: {final_plan['direct_response']}
297
- Reflection: {reflection.get('reflection', 'No improvements suggested')}"""
298
-
299
- except Exception as e:
300
- return f"Error executing plan: {str(e)}"
301
-
302
-
303
  agent = Agent()
 
304
 
305
- query_list = ["I am traveling to Japan from Lithuania, I have 1500 of local currency, how much of Japaese currency will I be able to get?",
306
  "How are you doing?"]
307
 
308
  for query in query_list:
 
1
+ from tools import convert_currency
2
+ from tools_agent import Agent
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  agent = Agent()
5
+ agent.add_tool(convert_currency)
6
 
7
+ query_list = ["I am traveling to Japan from Serbia, I have 1500 of local currency, how much of Japaese currency will I be able to get?",
8
  "How are you doing?"]
9
 
10
  for query in query_list: