serverdaun commited on
Commit
56ea4ef
·
1 Parent(s): 4374e3a

add additional math tools and analyze image tool

Browse files
Files changed (1) hide show
  1. tools.py +176 -1
tools.py CHANGED
@@ -5,7 +5,11 @@ from langchain_community.document_loaders import ArxivLoader
5
  from config import TAVILY_API_KEY
6
  import requests
7
  from bs4 import BeautifulSoup
8
-
 
 
 
 
9
 
10
  #=========================================
11
  # Search Tools
@@ -224,3 +228,174 @@ def modulus(x: float, y: float) -> float:
224
  float: The modulus of x and y.
225
  """
226
  return x % y
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  from config import TAVILY_API_KEY
6
  import requests
7
  from bs4 import BeautifulSoup
8
+ from PIL import Image
9
+ from pathlib import Path
10
+ import base64
11
+ from openai import AzureOpenAI
12
+ from config import MODEL_NAME, MODEL_API_VERSION, MODEL_ENDPOINT, MODEL_KEY
13
 
14
  #=========================================
15
  # Search Tools
 
228
  float: The modulus of x and y.
229
  """
230
  return x % y
231
+
232
+ @tool
233
+ def is_commutative(set_elements: list, operation_table: list) -> bool:
234
+ """
235
+ Check if the operation is commutative for the given set and operation table.
236
+ Args:
237
+ set_elements (list): List of elements in the set.
238
+ operation_table (list): 2D list representing the operation table.
239
+ Returns:
240
+ bool: True if commutative, False otherwise.
241
+ """
242
+ n = len(set_elements)
243
+ for i in range(n):
244
+ for j in range(n):
245
+ if operation_table[i][j] != operation_table[j][i]:
246
+ return False
247
+ return True
248
+
249
+ @tool
250
+ def commutativity_counterexample_pairs(set_elements: list, operation_table: list) -> list:
251
+ """
252
+ Return all pairs (as tuples) where commutativity fails: (x, y) such that x*y != y*x.
253
+ Args:
254
+ set_elements (list): List of elements in the set.
255
+ operation_table (list): 2D list representing the operation table.
256
+ Returns:
257
+ list: List of tuples (x, y) where commutativity fails.
258
+ """
259
+ n = len(set_elements)
260
+ pairs = []
261
+ for i in range(n):
262
+ for j in range(n):
263
+ if operation_table[i][j] != operation_table[j][i]:
264
+ pairs.append((set_elements[i], set_elements[j]))
265
+ return pairs
266
+
267
+ @tool
268
+ def commutativity_counterexample_elements(set_elements: list, operation_table: list) -> str:
269
+ """
270
+ Return the set of elements involved in any commutativity counter-example, as a sorted, comma-separated string.
271
+ Args:
272
+ set_elements (list): List of elements in the set.
273
+ operation_table (list): 2D list representing the operation table.
274
+ Returns:
275
+ str: Sorted, comma-separated string of elements involved in any commutativity counter-example.
276
+ """
277
+ involved = set()
278
+ n = len(set_elements)
279
+ for i in range(n):
280
+ for j in range(n):
281
+ if operation_table[i][j] != operation_table[j][i]:
282
+ involved.add(set_elements[i])
283
+ involved.add(set_elements[j])
284
+ return ",".join(sorted(involved))
285
+
286
+ @tool
287
+ def is_associative(set_elements: list, operation_table: list) -> bool:
288
+ """
289
+ Check if the operation is associative for the given set and operation table.
290
+ Args:
291
+ set_elements (list): List of elements in the set.
292
+ operation_table (list): 2D list representing the operation table.
293
+ Returns:
294
+ bool: True if associative, False otherwise.
295
+ """
296
+ n = len(set_elements)
297
+ idx = {e: i for i, e in enumerate(set_elements)}
298
+ for i in range(n):
299
+ for j in range(n):
300
+ for k in range(n):
301
+ a = operation_table[i][j]
302
+ a_idx = idx[a]
303
+ left = operation_table[a_idx][k]
304
+ b = operation_table[j][k]
305
+ b_idx = idx[b]
306
+ right = operation_table[i][b_idx]
307
+ if left != right:
308
+ return False
309
+ return True
310
+
311
+ @tool
312
+ def find_identity_element(set_elements: list, operation_table: list) -> str:
313
+ """
314
+ Find the identity element in the set, if it exists.
315
+ Args:
316
+ set_elements (list): List of elements in the set.
317
+ operation_table (list): 2D list representing the operation table.
318
+ Returns:
319
+ str: The identity element, or an empty string if none exists.
320
+ """
321
+ n = len(set_elements)
322
+ for i in range(n):
323
+ candidate = set_elements[i]
324
+ is_identity = True
325
+ for j in range(n):
326
+ if operation_table[i][j] != set_elements[j] or operation_table[j][i] != set_elements[j]:
327
+ is_identity = False
328
+ break
329
+ if is_identity:
330
+ return candidate
331
+ return ""
332
+
333
+ @tool
334
+ def find_inverses(set_elements: list, operation_table: list) -> dict:
335
+ """
336
+ For each element, find its inverse with respect to the operation, if it exists.
337
+ Args:
338
+ set_elements (list): List of elements in the set.
339
+ operation_table (list): 2D list representing the operation table.
340
+ Returns:
341
+ dict: Dictionary mapping each element to its inverse (or None if no inverse exists).
342
+ """
343
+ n = len(set_elements)
344
+ identity = find_identity_element(set_elements, operation_table)
345
+ if not identity:
346
+ return {e: None for e in set_elements}
347
+ idx = {e: i for i, e in enumerate(set_elements)}
348
+ identity_idx = idx[identity]
349
+ inverses = {}
350
+ for i in range(n):
351
+ found = None
352
+ for j in range(n):
353
+ if operation_table[i][j] == identity and operation_table[j][i] == identity:
354
+ found = set_elements[j]
355
+ break
356
+ inverses[set_elements[i]] = found
357
+ return inverses
358
+
359
+ #=========================================
360
+ # Image Tools
361
+ #=========================================
362
+ @tool
363
+ def analyze_image(question: str, path: str) -> str:
364
+ """
365
+ Analyze image and answer question regarding it.
366
+ Args:
367
+ question (str): The question to ask about the image.
368
+ path (str): The path to the image file.
369
+ Returns:
370
+ str: The answer to the question about the image.
371
+ """
372
+ # path = "data/cca530fc-4052-43b2-b130-b30968d8aa44.png"
373
+
374
+ client = AzureOpenAI(
375
+ api_version=MODEL_API_VERSION,
376
+ azure_endpoint=MODEL_ENDPOINT,
377
+ api_key=MODEL_KEY,
378
+ )
379
+
380
+ p = Path(path).expanduser().resolve()
381
+ if not p.exists():
382
+ raise ValueError(f"Image file does not exist: {p}")
383
+
384
+ mime = "image/png" if p.suffix.lower() == ".png" else "image/jpeg"
385
+ with open(p, "rb") as f:
386
+ base64_image = f"data:{mime};base64,{base64.b64encode(f.read()).decode('utf-8')}"
387
+
388
+ response = client.chat.completions.create(
389
+ model=MODEL_NAME,
390
+ messages=[
391
+ {
392
+ "role": "user",
393
+ "content": [
394
+ {"type": "text", "text": question},
395
+ {"type": "image_url", "image_url": {"url": base64_image}, "detail": "high"}
396
+ ]
397
+ }
398
+ ]
399
+ )
400
+
401
+ return response.choices[0].message.content.strip()