Peter Larnholt commited on
Commit
b4f2fa1
·
1 Parent(s): 1f77df0

Recreate simple_tool_chat.py with improved features and error handling

Browse files
Files changed (1) hide show
  1. simple_tool_chat.py +131 -60
simple_tool_chat.py CHANGED
@@ -60,11 +60,46 @@ tools = [
60
  "required": ["city"]
61
  }
62
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
  ]
65
 
66
  # Tool implementations
67
  def calculator(expression: str) -> str:
 
68
  try:
69
  result = eval(expression, {"__builtins__": {}, "math": math})
70
  return str(result)
@@ -72,25 +107,45 @@ def calculator(expression: str) -> str:
72
  return f"Error: {str(e)}"
73
 
74
  def get_current_time() -> str:
 
75
  return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
76
 
77
  def get_weather(city: str) -> str:
 
78
  weather_data = {
79
  "paris": "18°C, sunny",
80
  "london": "15°C, cloudy",
81
  "new york": "22°C, partly cloudy",
82
  "tokyo": "25°C, clear",
 
 
 
 
83
  }
84
  return weather_data.get(city.lower(), f"Weather data not available for {city}")
85
 
 
 
 
 
 
 
 
 
 
86
  # Function dispatcher
87
  def execute_tool(tool_name: str, arguments: dict) -> str:
 
88
  if tool_name == "calculator":
89
  return calculator(arguments["expression"])
90
  elif tool_name == "get_current_time":
91
  return get_current_time()
92
  elif tool_name == "get_weather":
93
  return get_weather(arguments["city"])
 
 
 
 
94
  else:
95
  return f"Unknown tool: {tool_name}"
96
 
@@ -102,64 +157,68 @@ def chat(user_message: str, messages: list = None):
102
  # Add user message
103
  messages.append({"role": "user", "content": user_message})
104
 
105
- # Call the model with tools (no tool_choice parameter)
106
- response = client.chat.completions.create(
107
- model="excom-ai",
108
- messages=messages,
109
- tools=tools,
110
- temperature=0.4
111
- )
112
-
113
- assistant_message = response.choices[0].message
114
-
115
- # Check if model wants to use tools
116
- if assistant_message.tool_calls:
117
- # Add assistant's tool call request to messages
118
- messages.append({
119
- "role": "assistant",
120
- "content": assistant_message.content,
121
- "tool_calls": [
122
- {
123
- "id": tc.id,
124
- "type": "function",
125
- "function": {
126
- "name": tc.function.name,
127
- "arguments": tc.function.arguments
 
 
128
  }
129
- }
130
- for tc in assistant_message.tool_calls
131
- ]
132
- })
133
 
134
- # Execute each tool call
135
- for tool_call in assistant_message.tool_calls:
136
- function_name = tool_call.function.name
137
- function_args = json.loads(tool_call.function.arguments)
138
 
139
- print(f"🔧 Calling tool: {function_name}({function_args})")
140
 
141
- # Execute the tool
142
- tool_result = execute_tool(function_name, function_args)
143
 
144
- # Add tool result to messages
145
- messages.append({
146
- "role": "tool",
147
- "tool_call_id": tool_call.id,
148
- "name": function_name,
149
- "content": tool_result
150
- })
151
 
152
- # Get final response from model
153
- final_response = client.chat.completions.create(
154
- model="excom-ai",
155
- messages=messages,
156
- temperature=0.4
157
- )
158
 
159
- return final_response.choices[0].message.content, messages
160
- else:
161
- # No tools needed, return direct response
162
- return assistant_message.content, messages
 
 
 
163
 
164
  def main():
165
  print("=" * 60)
@@ -169,28 +228,40 @@ def main():
169
  print(" • calculator - Evaluate math expressions")
170
  print(" • get_current_time - Get current date/time")
171
  print(" • get_weather - Get weather for cities")
172
- print("\nType 'quit' or 'exit' to end.")
 
 
 
173
  print("=" * 60)
174
  print()
175
 
176
  messages = []
177
 
178
  while True:
179
- user_input = input("You: ").strip()
 
180
 
181
- if user_input.lower() in ['quit', 'exit', 'q']:
182
- print("Goodbye!")
183
- break
184
 
185
- if not user_input:
186
- continue
 
 
 
 
 
187
 
188
- try:
189
  response, messages = chat(user_input, messages)
190
  print(f"Assistant: {response}\n")
 
 
 
 
191
  except Exception as e:
192
  print(f"❌ Error: {e}\n")
193
- # Reset messages on error
194
  messages = []
195
 
196
  if __name__ == "__main__":
 
60
  "required": ["city"]
61
  }
62
  }
63
+ },
64
+ {
65
+ "type": "function",
66
+ "function": {
67
+ "name": "word_counter",
68
+ "description": "Counts the number of words in the given text",
69
+ "parameters": {
70
+ "type": "object",
71
+ "properties": {
72
+ "text": {
73
+ "type": "string",
74
+ "description": "Text to count words in"
75
+ }
76
+ },
77
+ "required": ["text"]
78
+ }
79
+ }
80
+ },
81
+ {
82
+ "type": "function",
83
+ "function": {
84
+ "name": "reverse_text",
85
+ "description": "Reverses the given text",
86
+ "parameters": {
87
+ "type": "object",
88
+ "properties": {
89
+ "text": {
90
+ "type": "string",
91
+ "description": "Text to reverse"
92
+ }
93
+ },
94
+ "required": ["text"]
95
+ }
96
+ }
97
  }
98
  ]
99
 
100
  # Tool implementations
101
  def calculator(expression: str) -> str:
102
+ """Evaluates a mathematical expression"""
103
  try:
104
  result = eval(expression, {"__builtins__": {}, "math": math})
105
  return str(result)
 
107
  return f"Error: {str(e)}"
108
 
109
  def get_current_time() -> str:
110
+ """Returns the current date and time"""
111
  return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
112
 
113
  def get_weather(city: str) -> str:
114
+ """Gets simulated weather for a city"""
115
  weather_data = {
116
  "paris": "18°C, sunny",
117
  "london": "15°C, cloudy",
118
  "new york": "22°C, partly cloudy",
119
  "tokyo": "25°C, clear",
120
+ "berlin": "16°C, rainy",
121
+ "sydney": "23°C, sunny",
122
+ "mumbai": "30°C, hot and humid",
123
+ "toronto": "12°C, cool",
124
  }
125
  return weather_data.get(city.lower(), f"Weather data not available for {city}")
126
 
127
+ def word_counter(text: str) -> str:
128
+ """Counts words in text"""
129
+ words = text.split()
130
+ return f"Word count: {len(words)}"
131
+
132
+ def reverse_text(text: str) -> str:
133
+ """Reverses text"""
134
+ return text[::-1]
135
+
136
  # Function dispatcher
137
  def execute_tool(tool_name: str, arguments: dict) -> str:
138
+ """Execute a tool by name with given arguments"""
139
  if tool_name == "calculator":
140
  return calculator(arguments["expression"])
141
  elif tool_name == "get_current_time":
142
  return get_current_time()
143
  elif tool_name == "get_weather":
144
  return get_weather(arguments["city"])
145
+ elif tool_name == "word_counter":
146
+ return word_counter(arguments["text"])
147
+ elif tool_name == "reverse_text":
148
+ return reverse_text(arguments["text"])
149
  else:
150
  return f"Unknown tool: {tool_name}"
151
 
 
157
  # Add user message
158
  messages.append({"role": "user", "content": user_message})
159
 
160
+ try:
161
+ # Call the model with tools (no tool_choice parameter)
162
+ response = client.chat.completions.create(
163
+ model="excom-ai",
164
+ messages=messages,
165
+ tools=tools,
166
+ temperature=0.4
167
+ )
168
+
169
+ assistant_message = response.choices[0].message
170
+
171
+ # Check if model wants to use tools
172
+ if assistant_message.tool_calls:
173
+ # Add assistant's tool call request to messages
174
+ messages.append({
175
+ "role": "assistant",
176
+ "content": assistant_message.content,
177
+ "tool_calls": [
178
+ {
179
+ "id": tc.id,
180
+ "type": "function",
181
+ "function": {
182
+ "name": tc.function.name,
183
+ "arguments": tc.function.arguments
184
+ }
185
  }
186
+ for tc in assistant_message.tool_calls
187
+ ]
188
+ })
 
189
 
190
+ # Execute each tool call
191
+ for tool_call in assistant_message.tool_calls:
192
+ function_name = tool_call.function.name
193
+ function_args = json.loads(tool_call.function.arguments)
194
 
195
+ print(f"🔧 Calling tool: {function_name}({function_args})")
196
 
197
+ # Execute the tool
198
+ tool_result = execute_tool(function_name, function_args)
199
 
200
+ # Add tool result to messages
201
+ messages.append({
202
+ "role": "tool",
203
+ "tool_call_id": tool_call.id,
204
+ "name": function_name,
205
+ "content": tool_result
206
+ })
207
 
208
+ # Get final response from model
209
+ final_response = client.chat.completions.create(
210
+ model="excom-ai",
211
+ messages=messages,
212
+ temperature=0.4
213
+ )
214
 
215
+ return final_response.choices[0].message.content, messages
216
+ else:
217
+ # No tools needed, return direct response
218
+ return assistant_message.content, messages
219
+
220
+ except Exception as e:
221
+ return f"Error: {e}", messages
222
 
223
  def main():
224
  print("=" * 60)
 
228
  print(" • calculator - Evaluate math expressions")
229
  print(" • get_current_time - Get current date/time")
230
  print(" • get_weather - Get weather for cities")
231
+ print(" word_counter - Count words in text")
232
+ print(" • reverse_text - Reverse text")
233
+ print("\nType 'quit', 'exit', or 'q' to end.")
234
+ print("Type 'reset' to clear conversation history.")
235
  print("=" * 60)
236
  print()
237
 
238
  messages = []
239
 
240
  while True:
241
+ try:
242
+ user_input = input("You: ").strip()
243
 
244
+ if user_input.lower() in ['quit', 'exit', 'q']:
245
+ print("Goodbye!")
246
+ break
247
 
248
+ if user_input.lower() == 'reset':
249
+ messages = []
250
+ print("🔄 Conversation history cleared.\n")
251
+ continue
252
+
253
+ if not user_input:
254
+ continue
255
 
 
256
  response, messages = chat(user_input, messages)
257
  print(f"Assistant: {response}\n")
258
+
259
+ except KeyboardInterrupt:
260
+ print("\n\nGoodbye!")
261
+ break
262
  except Exception as e:
263
  print(f"❌ Error: {e}\n")
264
+ # Reset messages on unexpected error
265
  messages = []
266
 
267
  if __name__ == "__main__":