simrunsharma commited on
Commit
eec1102
·
verified ·
1 Parent(s): c3e3893

Adding in tool calling

Browse files
Files changed (2) hide show
  1. app.py +165 -6
  2. requirements.txt +3 -1
app.py CHANGED
@@ -6,10 +6,10 @@ from openai import OpenAI
6
  # from IPython.display import display, Markdown
7
  import gradio as gr
8
  # from dotenv import load_dotenv
9
- # import json
10
  import uuid
11
- # import random
12
- # import requests
13
  import chromadb
14
  from pprint import pprint
15
 
@@ -346,6 +346,140 @@ collection.add(
346
  documents=chunks
347
  )
348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
 
350
  #System message---------------------
351
  system_message = """
@@ -384,7 +518,7 @@ def respond_system_enhanced (message, history):
384
  )
385
 
386
  #logs for debugging
387
- #lets just give the closest distance one as context
388
  context = "\n--\n".join(results['documents'][0])
389
  print(f'User message:\n{message}\n')
390
  print('Context this turn:\n', context)
@@ -401,12 +535,37 @@ def respond_system_enhanced (message, history):
401
  # Call LLM
402
  response = client.chat.completions.create(
403
  model = "gpt-4.1-mini",
404
- messages = messages
 
405
  )
406
 
407
-
408
  message = response.choices[0].message
409
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
  return (message.content)
411
 
412
 
 
6
  # from IPython.display import display, Markdown
7
  import gradio as gr
8
  # from dotenv import load_dotenv
9
+ import json
10
  import uuid
11
+ import random
12
+ import requests
13
  import chromadb
14
  from pprint import pprint
15
 
 
346
  documents=chunks
347
  )
348
 
349
+ #Tools-----------------------------
350
+ tools = []
351
+
352
+ #Tool Handling --------------------
353
+ #PUSHOVER CREDENTIALS
354
+ #Creating the pushover identification information
355
+ pushover_user = os.getenv("PUSHOVER_USER")
356
+ pushover_token = os.getenv("PUSHOVER_TOKEN")
357
+ pushover_url = 'https://api.pushover.net/1/messages.json'
358
+
359
+ def send_notifications(message:str):
360
+ payload = {'user' : pushover_user,"token" : pushover_token, 'message': message}
361
+ requests.post(url = pushover_url, data=payload)
362
+
363
+ #PUSHOVER CREDENTIALS
364
+ #Creating the pushover identification information
365
+ pushover_user = os.getenv("PUSHOVER_USER")
366
+ pushover_token = os.getenv("PUSHOVER_TOKEN")
367
+ pushover_url = 'https://api.pushover.net/1/messages.json'
368
+
369
+ # print(pushover_user)
370
+
371
+ #creating the def send notifications:
372
+ # import requests
373
+
374
+ def send_notifications(message:str):
375
+ payload = {'user' : pushover_user,"token" : pushover_token, 'message': message}
376
+ requests.post(url = pushover_url, data=payload)
377
+
378
+ #Testing send notification
379
+ # send_notifications('June 8, 2026 Three Whistles')
380
+
381
+ # This is not a dictionary. This is a description card written in JSON format.
382
+ # We are describing the tool to OpenAI so it knows how to use it.
383
+ # Think of it like a form or a menu card. Not real Python objects.
384
+ #DESCRIBE PUSHOVER AS AN LLM TOOL
385
+ send_notifications_function = {
386
+
387
+ # The name of the tool OpenAI will request when it wants to use it
388
+ 'name': 'send_notifications',
389
+
390
+ # When should OpenAI use this tool? This description tells it.
391
+ 'description': 'Sends a push notification to the real-world version of you via Pushover on mobile. Use this if the user needs to alert the real-world version of you',
392
+ 'parameters': {
393
+
394
+ 'type': 'object',
395
+ 'properties': {
396
+
397
+ 'message': {
398
+ 'type': 'string',
399
+
400
+ 'description': 'The notification message the user wants sent to their device'
401
+ }
402
+
403
+
404
+ },
405
+
406
+
407
+ 'required': ['message']
408
+ }
409
+ }
410
+
411
+ #adding this tool to the tool list:
412
+ tools.append({"type" : "function", "function":send_notifications_function})
413
+
414
+ #Dice_roll---------------
415
+ # import random
416
+
417
+ #creating roll dice function
418
+ def dice_roll():
419
+ result = random.randint(1,6)
420
+ return result
421
+
422
+ #creating roll dice description of tool for LLM:
423
+ roll_dice_function = {
424
+ 'name' : "dice_roll",
425
+ 'description': 'This is a function where you can roll a dice and can see the number you get from the roll',
426
+ "parameters": {
427
+
428
+ },
429
+ "required" : []
430
+ }
431
+
432
+ #appending this to our available tools
433
+ tools.append({"type" : "function", "function" : roll_dice_function})
434
+
435
+
436
+ #Handle Tool Call -----------------
437
+ def handle_tool_call(tool_calls:list):
438
+
439
+
440
+ tool_call_results = []
441
+
442
+ for tool_call in tool_calls:
443
+
444
+ function_name = tool_call.function.name
445
+
446
+ # --- for debugging
447
+ # print(f"the function name is {function_name}")
448
+
449
+ # tool_call = tools_calls[0] #this is because we only have one tool thus far
450
+
451
+ args = json.loads(tool_call.function.arguments)
452
+
453
+ if function_name == 'send_notifications':
454
+ send_notifications(args['message']) #sent to pushover
455
+
456
+ content = f"Sent Notification: {args['message']}"
457
+
458
+ elif function_name == "dice_roll":
459
+
460
+ content = f' Rolled: {dice_roll()}'
461
+
462
+ # elif function_name == "insert_function3_name":
463
+
464
+ # content =insert_function3_name (args['message']})
465
+
466
+ else:
467
+ content = f"Unknown function: {function_name}"
468
+
469
+ #package into a dictionary for the llm to see what we got out from the tool call
470
+ tool_call_result = {
471
+ 'role' : 'tool',
472
+ 'content' : content ,
473
+ 'tool_call_id' : tool_call.id
474
+ }
475
+
476
+ print(f"this is what the tool_call_result from handle tool_call looks like: {tool_call_result}")
477
+
478
+ #appending each tool_call_result to the tool_call_results list of dictionaries
479
+ tool_call_results.append(tool_call_result)
480
+
481
+ return tool_call_results
482
+
483
 
484
  #System message---------------------
485
  system_message = """
 
518
  )
519
 
520
  #logs for debugging
521
+ #lets just give the 3 most relevant chunks
522
  context = "\n--\n".join(results['documents'][0])
523
  print(f'User message:\n{message}\n')
524
  print('Context this turn:\n', context)
 
535
  # Call LLM
536
  response = client.chat.completions.create(
537
  model = "gpt-4.1-mini",
538
+ messages = messages,
539
+ tools = tools
540
  )
541
 
542
+ #record message
543
  message = response.choices[0].message
544
 
545
+ print("message before while loop", message)
546
+
547
+
548
+
549
+ while message.tool_calls:
550
+ # from pprint import pprint
551
+ pprint(message.tool_calls)
552
+ #we want to pass the list of tool calls to out=r handle tool call function
553
+ tool_call = message.tool_calls
554
+ tool_call_result = handle_tool_call(message.tool_calls)
555
+
556
+ #we want to append the message with the user request and the first two tool call requests
557
+ messages.append(message)
558
+ #We also want append to append the toolcall results with the dictionaries of the content return from each tool call
559
+ messages.extend(tool_call_result)
560
+
561
+ response = client.chat.completions.create(
562
+ model = "gpt-4.1-mini",
563
+ messages = messages,
564
+ tools=tools
565
+ )
566
+
567
+ message = response.choices[0].message
568
+
569
  return (message.content)
570
 
571
 
requirements.txt CHANGED
@@ -7,4 +7,6 @@
7
  #to install into our .py file
8
  gradio
9
  openai
10
- chromadb
 
 
 
7
  #to install into our .py file
8
  gradio
9
  openai
10
+ chromadb
11
+ requests
12
+ random