Browse Source

Merge pull request #295 from arunabeshc/arunabesh

AI Booking Chatbot and Personal Story Writer
pull/312/merge
Ed Donner 4 weeks ago committed by GitHub
parent
commit
572a3d4931
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 762
      week2/community-contributions/AI Booking Chatbot.ipynb
  2. 428
      week2/community-contributions/Personal Story Writer.ipynb

762
week2/community-contributions/AI Booking Chatbot.ipynb

@ -0,0 +1,762 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d006b2ea-9dfe-49c7-88a9-a5a0775185fd",
"metadata": {},
"source": [
"# Additional End of week Exercise - week 2\n",
"\n",
"Now use everything you've learned from Week 2 to build a full prototype for the technical question/answerer you built in Week 1 Exercise.\n",
"\n",
"This should include a Gradio UI, streaming, use of the system prompt to add expertise, and the ability to switch between models. Bonus points if you can demonstrate use of a tool!\n",
"\n",
"If you feel bold, see if you can add audio input so you can talk to it, and have it respond with audio. ChatGPT or Claude can help you, or email me if you have questions.\n",
"\n",
"I will publish a full solution here soon - unless someone beats me to it...\n",
"\n",
"There are so many commercial applications for this, from a language tutor, to a company onboarding solution, to a companion AI to a course (like this one!) I can't wait to see your results."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "a07e7793-b8f5-44f4-aded-5562f633271a",
"metadata": {},
"outputs": [],
"source": [
"# imports\n",
"\n",
"import os\n",
"import json\n",
"from dotenv import load_dotenv\n",
"from openai import OpenAI\n",
"import gradio as gr\n",
"import base64\n",
"from io import BytesIO\n",
"import tempfile\n",
"import subprocess\n",
"from pydub import AudioSegment\n",
"import time\n",
"import anthropic"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "717ea9d4-1e72-4035-b7c5-5d61da5b8ea3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"OpenAI API Key exists and begins sk-proj-\n"
]
}
],
"source": [
"# Initialization\n",
"\n",
"load_dotenv(override=True)\n",
"\n",
"openai_api_key = os.getenv('OPENAI_API_KEY')\n",
"if openai_api_key:\n",
" print(f\"OpenAI API Key exists and begins {openai_api_key[:8]}\")\n",
"else:\n",
" print(\"OpenAI API Key not set\")\n",
" \n",
"gpt_model = \"gpt-4o-mini\"\n",
"claude_model = \"claude-3-haiku-20240307\"\n",
"\n",
"openai = OpenAI()\n",
"claude = anthropic.Anthropic()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "cc78f4fd-9920-4872-9117-90cd2aeb2a06",
"metadata": {},
"outputs": [],
"source": [
"system_message = \"You are a helpful assistant. \"\n",
"system_message += \"Give short, courteous answers. You can check ticket price, ticket availability, and reserve tickets for users. \"\n",
"system_message += \"Always be accurate. If you don't know the answer, say so.\""
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "b2701cc0-6403-4880-9b31-e6e39e89feb4",
"metadata": {},
"outputs": [],
"source": [
"# Let's start by making a useful function\n",
"\n",
"ticket_prices = {\"london\": \"$799\", \"paris\": \"$899\", \"tokyo\": \"$1400\", \"berlin\": \"$499\"}\n",
"\n",
"def get_ticket_price(destination_city):\n",
" print(f\"Tool get_ticket_price called for {destination_city}\")\n",
" city = destination_city.lower()\n",
" return ticket_prices.get(city, \"Unknown\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5e33902f-c2c3-4fb0-b01d-a346a4dff811",
"metadata": {},
"outputs": [],
"source": [
"ticket_availability = {\"london\": \"20\", \"paris\": \"90\", \"tokyo\": \"100\", \"berlin\": \"2\"}"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "27dfca47-2a38-49f3-8905-f583d98710a5",
"metadata": {},
"outputs": [],
"source": [
"# Let's start by making a useful function\n",
"def get_ticket_availability(destination_city):\n",
" print(f\"Tool get_ticket_availability called for {destination_city}\")\n",
" available = destination_city.lower()\n",
" return ticket_availability.get(available, \"Unknown\")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "6ae7371b-031e-47d7-afaf-42d6758ccd92",
"metadata": {},
"outputs": [],
"source": [
"def get_ticket_price_availability(destination_city):\n",
" print(f\"Tool get_ticket_price_availability called for {destination_city}\")\n",
" available = destination_city.lower()\n",
" price = destination_city.lower()\n",
" return ticket_price.get(price, \"Unknown\"), ticket_availability.get(available, \"Unknown\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "c919b13a-50b6-4510-8e9d-02cdfd95cb98",
"metadata": {},
"outputs": [],
"source": [
"def book_ticket(destination_city,price,availability,no_of_tickets):\n",
" status=\"\"\n",
" if availability == 0:\n",
" status=\"Cannot book a ticket, no seat available\\n\"\n",
" elif (int(availability)-int(no_of_tickets)) < 0:\n",
" status=\"Cannot book a ticket, no seat available\\n\"\n",
" else:\n",
" print(f\"Tool book_function called for {destination_city}\")\n",
" f = open(\"C:/Users/aruna/Desktop/book_status.txt\", \"a\")\n",
" f.write(f\"{no_of_tickets} ticket/s to {destination_city} booked for {price} x {no_of_tickets}, currently available - {int(availability)-int(no_of_tickets)}\")\n",
" f.write(\"\\n\")\n",
" f.close()\n",
" ticket_availability[destination_city.lower()]=str(int(availability)-int(no_of_tickets))\n",
" \n",
" status=\"Ticket reservation is a success\\n\"\n",
" return status"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "d2628781-6f5e-4ac1-bbe3-2e08aa0aae0d",
"metadata": {},
"outputs": [],
"source": [
"book_function = {\n",
" \"name\": \"book_ticket\",\n",
" \"description\": \"Book the ticket based on the ticket price and/ or availability as requested by the user. For example, when a \\\n",
" user asks to purchase one or more tickets to Tokyo after getting to know the ticket price and/or the availability, then \\\n",
" proceed with this tool call. Else, request the user to either ask for ticket price or availability first. Please help the customer in booking the ticket/s if tickets are available. But before each time\\\n",
" you book, ask confirmation from the user before proceeding with booking.\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"destination_city\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The city that the customer wants to travel to\",\n",
" },\n",
" \"price\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The price of the ticket to the city\",\n",
" },\n",
" \"availability\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"ticket availability to the city the customer wants to travel to\",\n",
" },\n",
" \"no_of_tickets\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"the number of tickets the customer wants to purchase/ book to the destination\",\n",
" }\n",
" },\n",
" \"required\": [\"destination_city\",\"price\",\"availability\",\"no_of_tickets\"],\n",
" \"additionalProperties\": False\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "480de296-4a36-4ec4-a5f6-149fc198c7a8",
"metadata": {},
"outputs": [],
"source": [
"# There's a particular dictionary structure that's required to describe our function:\n",
"\n",
"price_function = {\n",
" \"name\": \"get_ticket_price\",\n",
" \"description\": \"Get the price of a one_way ticket to the destination city. Call this whenever you need to know the ticket price, for example when a customer asks 'How much is a ticket to this city'\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"destination_city\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The city that the customer wants to travel to\",\n",
" },\n",
" },\n",
" \"required\": [\"destination_city\"],\n",
" \"additionalProperties\": False\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "cf1b3e35-08ee-478e-aa1c-534418d78daf",
"metadata": {},
"outputs": [],
"source": [
"availability_function = {\n",
" \"name\": \"get_ticket_availability\",\n",
" \"description\": \"Get the availability of a one-way ticket to the destination city. Call this whenever you need to know the ticket availability, for example when a customer asks 'What is the ticket availability to this city'\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"destination_city\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The city that the customer wants to travel to\",\n",
" },\n",
" },\n",
" \"required\": [\"destination_city\"],\n",
" \"additionalProperties\": False\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "73e4c8a2-c034-41a4-9b97-7b2aa4aca504",
"metadata": {},
"outputs": [],
"source": [
"ticket_price_availability_function = {\n",
" \"name\": \"get_ticket_price_availability\",\n",
" \"description\": \"Get the price or availability of a one-way ticket to the destination city. Call this whenever you need to know the ticket price and availability, for example when a customer asks 'What is the ticket availability and price to this city'\\\n",
" or 'what is the price and ticket for the city?'\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"destination_city\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The city that the customer wants to travel to\",\n",
" },\n",
" },\n",
" \"required\": [\"destination_city\"],\n",
" \"additionalProperties\": False\n",
" }\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "1d5d74a0-9c25-46a4-84ee-1f700bd55fa7",
"metadata": {},
"outputs": [],
"source": [
"# And this is included in a list of tools:\n",
"\n",
"tools = [{\"type\": \"function\", \"function\": price_function},\n",
" {\"type\": \"function\", \"function\": availability_function},\n",
" {\"type\": \"function\", \"function\": ticket_price_availability_function},\n",
" {\"type\": \"function\", \"function\": book_function}]"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "fa18f535-f8a7-4386-b39a-df0f84d23406",
"metadata": {},
"outputs": [],
"source": [
"def play_audio(audio_segment):\n",
" temp_dir = tempfile.gettempdir()\n",
" temp_path = os.path.join(temp_dir, \"temp_audio.wav\")\n",
" try:\n",
" audio_segment.export(temp_path, format=\"wav\")\n",
" time.sleep(3) # Student Dominic found that this was needed. You could also try commenting out to see if not needed on your PC\n",
" subprocess.call([\n",
" \"ffplay\",\n",
" \"-nodisp\",\n",
" \"-autoexit\",\n",
" \"-hide_banner\",\n",
" temp_path\n",
" ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)\n",
" finally:\n",
" try:\n",
" os.remove(temp_path)\n",
" except Exception:\n",
" pass\n",
" \n",
"def talker(message):\n",
" response = openai.audio.speech.create(\n",
" model=\"tts-1\",\n",
" voice=\"alloy\", # Also, try replacing with onyx\n",
" input=message\n",
" )\n",
" audio_stream = BytesIO(response.content)\n",
" audio = AudioSegment.from_file(audio_stream, format=\"mp3\")\n",
" play_audio(audio)\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "b588d711-5f20-4a3a-9422-81a1fda8d5b0",
"metadata": {},
"outputs": [],
"source": [
"# We have to write that function handle_tool_call:\n",
"\n",
"def handle_tool_call1(message):\n",
" tool_call = message.tool_calls[0]\n",
" arguments = json.loads(tool_call.function.arguments)\n",
" name = json.dumps(tool_call.function.name)\n",
" city = arguments.get('destination_city')\n",
" no = arguments.get('no_of_tickets')\n",
" \n",
" if name.replace('\"','') == \"get_ticket_price\":\n",
" price = get_ticket_price(city)\n",
" response = {\n",
" \"role\": \"tool\",\n",
" \"content\": json.dumps({\"destination_city\": city,\"price\": price}),\n",
" \"tool_call_id\": tool_call.id\n",
" }\n",
" elif name.replace('\"','') == \"book_ticket\":\n",
" price = get_ticket_price(city)\n",
" availability = get_ticket_availability(city)\n",
" booked=book_ticket(city,price,availability,no)\n",
" response = {\n",
" \"role\": \"tool\",\n",
" \"content\": json.dumps({\"destination_city\": city, \"number of tickets\":no, \"booking_status\": booked}),\n",
" \"tool_call_id\": tool_call.id\n",
" }\n",
" else :\n",
" availability = get_ticket_availability(city)\n",
" response = {\n",
" \"role\": \"tool\",\n",
" \"content\": json.dumps({\"destination_city\": city,\"availability\": availability},),\n",
" \"tool_call_id\": tool_call.id\n",
" }\n",
" \n",
" return response, city"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "e74eee70-f89e-4c03-922c-74f9ab567a4c",
"metadata": {},
"outputs": [],
"source": [
"def chat_open_ai(history):\n",
" messages = [{\"role\": \"system\", \"content\": system_message}] + history \n",
" response = openai.chat.completions.create(model=gpt_model, messages=messages, tools=tools)\n",
" if response.choices[0].finish_reason==\"tool_calls\":\n",
" message = response.choices[0].message\n",
" print(message)\n",
" tool_call = message.tool_calls[0]\n",
" arguments = json.loads(tool_call.function.arguments)\n",
" name = json.dumps(tool_call.function.name)\n",
" city = arguments.get('destination_city')\n",
" \n",
" if name.replace('\"','') == \"book_ticket\":\n",
" response, city = handle_tool_call1(message)\n",
" messages.append(message)\n",
" messages.append(response)\n",
" # image = artist(city)\n",
" response = openai.chat.completions.create(model=gpt_model, messages=messages, tools=tools)\n",
" elif name.replace('\"','') == \"get_ticket_price_availability\":\n",
" price = get_ticket_price(city)\n",
" availability = get_ticket_availability(city)\n",
" response = {\n",
" \"role\": \"tool\",\n",
" \"content\": json.dumps({\"destination_city\": city,\"price\": price,\"availability\": availability}),\n",
" \"tool_call_id\": tool_call.id\n",
" }\n",
" messages.append(message)\n",
" messages.append(response)\n",
" print(messages)\n",
" response = openai.chat.completions.create(model=gpt_model, messages=messages, tools=tools) \n",
" else: \n",
" response, city = handle_tool_call1(message)\n",
" messages.append(message)\n",
" messages.append(response)\n",
" # image = artist(city)\n",
" response = openai.chat.completions.create(model=gpt_model, messages=messages, tools=tools)\n",
" \n",
" reply = response.choices[0].message.content\n",
" history += [{\"role\":\"assistant\", \"content\":reply}]\n",
"\n",
" # Comment out or delete the next line if you'd rather skip Audio for now..\n",
" talker(reply)\n",
" \n",
" # return history, image\n",
" return history"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "b8f25812-2609-4e26-b929-9cee2d1e4467",
"metadata": {},
"outputs": [],
"source": [
"tools_claude=[\n",
" {\n",
" \"name\": \"get_ticket_price_availability\",\n",
" \"description\": \"Get the availability of a one-way ticket to the destination city or the price. Call this whenever you need to know the ticket price or availability or both, for example, when a customer asks 'What is the ticket availability and/ or price to this city'\",\n",
" \"input_schema\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"destination_city\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The city that the customer wants to travel to\",\n",
" },\n",
" },\n",
" \"required\": [\"destination_city\"]\n",
" ,\"additionalProperties\": False\n",
" }\n",
" }\n",
" ]\n",
"tool_choice = [{\"type\": \"tool\", \"name\": \"get_ticket_price_availability\"}]"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "1728e70b-596c-4048-8c02-ac3c26756470",
"metadata": {},
"outputs": [],
"source": [
"def chat_claude(history):\n",
" for element in history:\n",
" del element[\"metadata\"]\n",
" del element[\"options\"]\n",
"\n",
" messages = history\n",
" response = claude.messages.create(\n",
" model=claude_model,\n",
" system=system_message,\n",
" messages=messages,\n",
" max_tokens=500,\n",
" tools=tools_claude\n",
" )\n",
" print(response.content[0])\n",
" if response.stop_reason==\"tool_use\": \n",
" if \"text=\" in str(response.content[0]):\n",
" # if response.content[0].text is None:\n",
" tool_name = response.content[1].name\n",
" tool_input = response.content[1].input\n",
" tool_id = response.content[1].id\n",
" tool_use=response.content[1]\n",
" else:\n",
" tool_name = response.content[0].name\n",
" tool_input = response.content[0].input\n",
" tool_id = response.content[0].id\n",
" tool_use=response.content[0]\n",
" \n",
" \n",
" city = tool_input.get('destination_city') \n",
" if tool_name == \"get_ticket_price_availability\":\n",
" price = get_ticket_price(city)\n",
" availability = get_ticket_availability(city)\n",
" result_dict = {\n",
" 'destination_city': city,\n",
" 'price': price,\n",
" 'availability': availability\n",
" }\n",
" messages += [{\"role\": \"user\",\"content\": json.dumps(result_dict)}]\n",
" response = claude.messages.create(\n",
" model=claude_model,\n",
" system=system_message,\n",
" messages=messages,\n",
" max_tokens=500,\n",
" # tools=tools_claude\n",
" ) \n",
" history.pop(len(history)-1)\n",
" print(history)\n",
" reply = response.content[0].text\n",
" history += [{\"role\":\"assistant\", \"content\":reply}]\n",
" # Comment out or delete the next line if you'd rather skip Audio for now..\n",
" # talker(reply)\n",
" \n",
" # return history, image\n",
" return history"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "a2547bb0-43a5-4b1d-8b9a-95da15a11040",
"metadata": {},
"outputs": [],
"source": [
"def chat1(history, Model):\n",
" # + [{\"role\": \"user\", \"content\": message}]\n",
" if Model==\"Open AI\":\n",
" history = chat_open_ai(history)\n",
" else:\n",
" history = chat_claude(history)\n",
" return history"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "36e11d99-9281-4efd-a792-dd4fa5935917",
"metadata": {},
"outputs": [],
"source": [
"def listen2(history):\n",
" import speech_recognition as sr\n",
"\n",
" r = sr.Recognizer()\n",
" with sr.Microphone() as source:\n",
" print(\"Speak now...\")\n",
" audio = r.listen(source, phrase_time_limit=30)\n",
" text=\"\"\n",
" try:\n",
" text = r.recognize_google(audio)\n",
" print(\"You said:\", text)\n",
" except sr.UnknownValueError:\n",
" print(\"Could not understand audio.\")\n",
"\n",
" history += [{\"role\":\"user\", \"content\":text}] \n",
" return \"\", history"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "23b102a4-e544-4560-acc8-a15620478582",
"metadata": {},
"outputs": [],
"source": [
"# import speech_recognition as sr\n",
"# from pydub import AudioSegment\n",
"# import simpleaudio as sa\n",
"\n",
"# def listener():\n",
"# recognizer = sr.Recognizer()\n",
" \n",
"# with sr.Microphone() as source:\n",
"# print(\"Listening... Speak now!\")\n",
"# recognizer.adjust_for_ambient_noise(source) # Adjust for background noise\n",
"# audio = recognizer.listen(source, phrase_time_limit=30)\n",
" \n",
"# try:\n",
"# print(\"Processing speech...\")\n",
"# text = recognizer.recognize_google(audio) # Use Google Speech-to-Text\n",
"# print(f\"You said: {text}\")\n",
"# return text\n",
"# except sr.UnknownValueError:\n",
"# print(\"Sorry, I could not understand what you said.\")\n",
"# return None\n",
"# except sr.RequestError:\n",
"# print(\"Could not request results, please check your internet connection.\")\n",
"# return None\n",
"\n",
"# # Example usage:\n",
"# # text = listener() # Listen for speech\n",
"# # if text:\n",
"# # print(f\"You just said: {text}\") "
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "133904cf-4d72-4552-84a8-76650f334857",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"* Running on local URL: http://127.0.0.1:7860\n",
"\n",
"To create a public link, set `share=True` in `launch()`.\n"
]
},
{
"data": {
"text/html": [
"<div><iframe src=\"http://127.0.0.1:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": []
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"with gr.Blocks() as ui:\n",
" with gr.Row():\n",
" chatbot = gr.Chatbot(height=300, type=\"messages\")\n",
" # image_output = gr.Image(height=500)\n",
" with gr.Row():\n",
" Model = gr.Dropdown([\"Open AI\",\"Claude\"],\n",
" # value=[\"Open AI\",\"Claude\"],\n",
" multiselect=False,\n",
" label=\"Model\",\n",
" interactive=True)\n",
" with gr.Row():\n",
" entry = gr.Textbox(label=\"Chat with our AI Assistant:\")\n",
" with gr.Row():\n",
" speak = gr.Button(\"click for voice search\") \n",
" with gr.Row():\n",
" clear = gr.Button(\"Clear\")\n",
"\n",
" def listen(history):\n",
" message, history=listen2(history)\n",
" return message, history\n",
"\n",
" def do_entry(message, history):\n",
" history += [{\"role\":\"user\", \"content\":message}]\n",
" return \"\", history\n",
"\n",
" entry.submit(do_entry, inputs=[entry, chatbot], outputs=[entry, chatbot]).then(\n",
" # chat, inputs=chatbot, outputs=[chatbot, image_output]\n",
" chat1, inputs=[chatbot, Model], outputs=[chatbot]\n",
" )\n",
" speak.click(listen, inputs=[chatbot], outputs=[entry, chatbot]).then(\n",
" chat1, inputs=[chatbot, Model], outputs=[chatbot]\n",
" )\n",
" clear.click(lambda: None, inputs=None, outputs=chatbot, queue=False)\n",
"\n",
"ui.launch(inbrowser=True)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "dc4a3844-194c-4af7-8ca8-2fc4edb74c11",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'london': '20', 'paris': '90', 'tokyo': '100', 'berlin': '2'}\n",
"Speak now...\n",
"You said: price of tickets to Tokyo\n",
"ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_ddXzm2cPBJ9SOsV8qI4L2FcB', function=Function(arguments='{\"destination_city\":\"Tokyo\"}', name='get_ticket_price'), type='function')])\n",
"Tool get_ticket_price called for Tokyo\n",
"Speak now...\n",
"You said: what is the price of two tickets to London\n",
"ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_lSNZCwaUdckvk3V0eTBlotRN', function=Function(arguments='{\"destination_city\":\"London\"}', name='get_ticket_price'), type='function')])\n",
"Tool get_ticket_price called for London\n",
"Speak now...\n",
"You said: can you please reserve two tickets for me to London\n",
"ChatCompletionMessage(content='First, I need to check the availability for the two tickets to London. Please hold on a moment.', refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_iA0D9tm2cTMf8J8KJc4gipFn', function=Function(arguments='{\"destination_city\":\"London\"}', name='get_ticket_availability'), type='function')])\n",
"Tool get_ticket_availability called for London\n",
"Speak now...\n",
"You said: yes please proceed\n",
"ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_JzJXFWFGhtG1jXiFlKtmZhGi', function=Function(arguments='{\"destination_city\":\"London\",\"price\":\"$799\",\"availability\":\"20 tickets available\",\"no_of_tickets\":\"2\"}', name='book_ticket'), type='function')])\n",
"Tool get_ticket_price called for London\n",
"Tool get_ticket_availability called for London\n",
"Tool book_function called for London\n",
"Speak now...\n",
"You said: what is the current availability of tickets to London\n",
"ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_eiHPAGAcbaFq3qzDf0a6idzG', function=Function(arguments='{\"destination_city\":\"London\"}', name='get_ticket_availability'), type='function')])\n",
"Tool get_ticket_availability called for London\n",
"Speak now...\n",
"You said: can you please reserve the remaining 18 tickets for me to London\n",
"Speak now...\n",
"You said: yes I do confirm\n",
"ChatCompletionMessage(content=None, refusal=None, role='assistant', annotations=[], audio=None, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_8uCQ91FCOGf4HjQnLNafmSs6', function=Function(arguments='{\"destination_city\":\"London\",\"price\":\"799\",\"availability\":\"18\",\"no_of_tickets\":\"18\"}', name='book_ticket'), type='function')])\n",
"Tool get_ticket_price called for London\n",
"Tool get_ticket_availability called for London\n",
"Tool book_function called for London\n",
"Speak now...\n",
"You said: what is the current availability of tickets to London\n",
"Speak now...\n",
"You said: that will be off thank you very much\n"
]
}
],
"source": [
"print(ticket_availability)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5166396e-6d8d-4cf2-982b-270d1c87a5ee",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "e871fc45-64db-4fb6-add7-569c8b30fe05",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

428
week2/community-contributions/Personal Story Writer.ipynb

@ -0,0 +1,428 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "de23bb9e-37c5-4377-9a82-d7b6c648eeb6",
"metadata": {},
"outputs": [],
"source": [
"# imports\n",
"\n",
"from dotenv import load_dotenv\n",
"import anthropic\n",
"import requests\n",
"from bs4 import BeautifulSoup\n",
"from selenium import webdriver\n",
"from selenium.webdriver.chrome.options import Options\n",
"import os\n",
"import json\n",
"from typing import List\n",
"from dotenv import load_dotenv\n",
"from IPython.display import Markdown, display, update_display\n",
"from openai import OpenAI\n",
"import gradio as gr # oh yeah!"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "1179b4c5-cd1f-4131-a876-4c9f3f38d2ba",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"OpenAI API Key exists and begins sk-proj-\n",
"Anthropic API Key exists and begins sk-ant-\n"
]
}
],
"source": [
"# Load environment variables in a file called .env\n",
"# Print the key prefixes to help with any debugging\n",
"\n",
"load_dotenv(override=True)\n",
"openai_api_key = os.getenv('OPENAI_API_KEY')\n",
"anthropic_api_key = os.getenv('ANTHROPIC_API_KEY')\n",
"\n",
"if openai_api_key:\n",
" print(f\"OpenAI API Key exists and begins {openai_api_key[:8]}\")\n",
"else:\n",
" print(\"OpenAI API Key not set\")\n",
" \n",
"if anthropic_api_key:\n",
" print(f\"Anthropic API Key exists and begins {anthropic_api_key[:7]}\")\n",
"else:\n",
" print(\"Anthropic API Key not set\")"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "797fe7b0-ad43-42d2-acf0-e4f309b112f0",
"metadata": {},
"outputs": [],
"source": [
"# Connect to OpenAI, Anthropic\n",
"\n",
"openai = OpenAI()\n",
"\n",
"claude = anthropic.Anthropic()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "bcb54183-45d3-4d08-b5b6-55e380dfdf1b",
"metadata": {},
"outputs": [],
"source": [
"gpt_model = \"gpt-4o-mini\"\n",
"claude_model = \"claude-3-haiku-20240307\"\n",
"\n",
"gpt_name=\"GPT\"\n",
"claude_name=\"Claude\"\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1df47dc7-b445-4852-b21b-59f0e6c2030f",
"metadata": {},
"outputs": [],
"source": [
"def call_gpt(Language, Genre, gpt_messages, claude_messages, Remarks):\n",
" \n",
" if Remarks == \"\":\n",
" # print(\"remarks is not there\")\n",
" gpt_system = f\"You are a chatbot who is a short story writer; Your name is g1. \\\n",
" Please write a story in markdown in {Language} , the genre being {Genre}. \\\n",
" Please also incorporate feedback such as areas of improvement (if any) coming from the user \\\n",
" and only publish the improved version without any extra comments.\"\n",
" else :\n",
" # print(\"remarks is there\")\n",
" gpt_system = f\"You are a chatbot who is a short story writer; Your name is g1. \\\n",
" Please write a story in markdown in {Language} , the genre being {Genre}. \\\n",
" The story should consist {Remarks}\\\n",
" Please also incorporate feedback such as areas of improvement (if any) coming from the user \\\n",
" and only publish the improved version without any extra comments.\"\n",
" \n",
" messages = [{\"role\": \"system\", \"content\": gpt_system}]\n",
" for gpt, claude in zip(gpt_messages, claude_messages):\n",
" messages.append({\"role\": \"assistant\", \"content\": gpt})\n",
" messages.append({\"role\": \"user\", \"content\": claude})\n",
" # print(messages)\n",
" \n",
" completion = openai.chat.completions.create(\n",
" model=gpt_model,\n",
" messages=messages\n",
" )\n",
" return completion.choices[0].message.content\n",
" \n",
" # stream = openai.chat.completions.create(\n",
" # model=gpt_model,\n",
" # messages=messages,\n",
" # stream=True\n",
" # )\n",
" # result = \"\"\n",
" # for chunk in stream:\n",
" # result += chunk.choices[0].delta.content or \"\"\n",
" # yield result"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "9dc6e913-02be-4eb6-9581-ad4b2cffa606",
"metadata": {},
"outputs": [],
"source": [
"# call_gpt()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "7d2ed227-48c9-4cad-b146-2c4ecbac9690",
"metadata": {},
"outputs": [],
"source": [
"def call_claude(Language, Genre, gpt_messages, claude_messages):\n",
"\n",
" claude_system = f\"You are a chatbot who is a short story analyser; Your name is c1. \\\n",
" You will accept an input story in {Genre} genre and {Language} language and publish only the areas of improvement if you find any with no other comments\"\n",
" \n",
" messages1 = []\n",
" for gpt, claude1 in zip(gpt_messages, claude_messages):\n",
" messages1.append({\"role\": \"user\", \"content\": gpt})\n",
" messages1.append({\"role\": \"assistant\", \"content\": claude1})\n",
" messages1.append({\"role\": \"user\", \"content\": gpt_messages[-1]})\n",
" # print(messages1)\n",
" message = claude.messages.create(\n",
" model=claude_model,\n",
" system=claude_system,\n",
" messages=messages1,\n",
" max_tokens=500\n",
" )\n",
" return message.content[0].text\n",
"\n",
" # result = claude.messages.stream(\n",
" # model=claude_model,\n",
" # max_tokens=1000,\n",
" # temperature=0.7,\n",
" # system=claude_system,\n",
" # messages=messages\n",
" # )\n",
" # response = \"\"\n",
" # with result as stream:\n",
" # for text in stream.text_stream:\n",
" # response += text or \"\"\n",
" # yield response\n",
"\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "0275b97f-7f90-4696-bbf5-b6642bd53cbd",
"metadata": {},
"outputs": [],
"source": [
"def Write_Me(Language, Genre, Iterations, Remarks):\n",
" \n",
" gpt_messages = [\"Hi I will share a story now!!\"]\n",
" claude_messages = [\"Please share, I will critique the story.\"]\n",
" \n",
" print(f\"{gpt_name}:\\n{gpt_messages[0]}\\n\")\n",
" print(f\"{claude_name}:\\n{claude_messages[0]}\\n\")\n",
"\n",
" for i in range(int(Iterations)):\n",
" gpt_next = call_gpt(Language, Genre, gpt_messages, claude_messages, Remarks)\n",
" print(f\"{gpt_name}:\\n{gpt_next}\\n\")\n",
" # yield gpt_next\n",
" gpt_messages.append(gpt_next)\n",
" \n",
" claude_next = f\"After {i+1} iterations, this is the critique for the provided story - \\\n",
" \\n\\n{call_claude(Language, Genre, gpt_messages, claude_messages)}\"\n",
" print(f\"{claude_name}:\\n{claude_next}\\n\")\n",
" # yield claude_next\n",
" claude_messages.append(claude_next)\n",
"\n",
" yield gpt_next, claude_next\n",
" \n",
" # yield gpt_next, claude_next\n",
" # return (gpt_next, claude_next)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "19e66ed3-d2c3-4a71-aec4-7869e5295215",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"* Running on local URL: http://127.0.0.1:7860\n",
"\n",
"To create a public link, set `share=True` in `launch()`.\n"
]
},
{
"data": {
"text/html": [
"<div><iframe src=\"http://127.0.0.1:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": []
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"GPT:\n",
"Hi I will share a story now!!\n",
"\n",
"Claude:\n",
"Please share, I will critique the story.\n",
"\n",
"GPT:\n",
"# ভডর আতঙিত অতিি\n",
"\n",
"বনгалর একটিরন কলকর বি, আরযন একজন সহসবক হি অনক খজ-খবর কর একটির ঘর খজছিল। পরিিত একটি অদত হর পর, স লকয করল ছবির কি একটিডরম।\n",
"\n",
"সরবশ করর পর, সর প একটিি রঙর স ও একটি ছবিখল। ছবির মধ মহি একটিিকটিিিিল। আরযন খব অবক হল, সময় কর জনয স ছবির দিগল। কিষণর মধই স একটিির হল।\n",
"\n",
"\"ভনতছ?\" স একটি শবদ আসছ। আরযন পিছন ফিিখল যর মধ একটির মহির দিি আছ।\n",
"\n",
"\"আমির জনয অপ করছিম,\" মহি বলল, তর গলখ থর হয় আসছিল শ। \"এটি একটি দলর রত।\"\n",
"\n",
"আরযন দল, কির থ অদত আওয়জ আসতগল। \"তিরব, করণ তি আমর দলগ দির ন।”\n",
"\n",
"“মহির কি হয়? আপন এতিৎকর করছন? তহলি হব?” আরযন যধ করছিল।\n",
"\n",
"তিি উপসিত হওয়র পর, আহিত আতিি আসতগল। আরযন খব ভত হয়ল করণ মহির মখ তর ক কখন কখনিত হচিল।\n",
"\n",
"“আমর আজ রর জনয মজ করত এসি, তি আমর সঙগ দি!” ত একসঙিৎকর করতগল।\n",
"\n",
"আরযন উপলবি করল য এটি একটি ভয়ঙকর ও হযকর পরিিি। সবই অত অদত ঘটনর দিিল। হঠৎ, ছবির মহি বলন, “তি যদিসতর, তব আমর দলরহণ কর!”\n",
"\n",
"এরপর শ হল খর একটি হরর পরিশ। আরযন ও তর বনর নি সমযগল। যদিও অনক ভয়, কি একসব হির বযবস করলল। তর বিির কথ মজর চরির সিয়, আর একসময় ত সবই একসঙ করসতগল।\n",
"\n",
"শ, ত তখন উপলবি করল য, ভয়বহতর মও আননর উপন লি আছ। বযকি যদিিকভ উদয ব এই ভ পরি মজর উপকিি কর, ত একজনর ঘম হর ভয় হয়য় হির স।\n",
"\n",
"আরযন এবর নতন বনবনক একটি নতন দিরহণ কর, যি এব ভয়র পিকত হয়। \n",
"\n",
"এই ছিল আরযনর ভ অবসর আতঙিত হওয়র অভিঞত, যিি অমর করখল।\n",
"\n",
"Claude:\n",
"After 1 iterations, this is the critique for the provided story - \n",
"\n",
"আইতম সমর উননতির সচন:\n",
"\n",
"1. কির শরধন চরিরটি আরিশদভ পরিচয।\n",
"2. ভ পরির বরণন আরিিত ও ভবময হত।\n",
"3. চরিরগির মধঘরষ, ডলগ ও সদ বিিময আরিক ও পণবনত হত।\n",
"4. কির শরধন চরির অভিঞত ও শি আর গভরতভ করত।\n",
"\n",
"GPT:\n",
"# ভডর আতঙিত অতিি\n",
"\n",
"বনগর একটিরনির বি, আরযন একটিঘ পরকির পর একটির ঘর খজছিল। আরযন, একজন করমঠ ও সহসবক, সদযই তর কলজ জবন শষ কর। নতন পরি নতন বনর খ এই শহর এস। পরতি অনক অদত কথ বলিল, কি ভয়ডরহন।\n",
"\n",
"একদিন, তিি একটি অদত হন, য শহরর প, খব পরন এবিল। সরবশ করর পর, তিি একটিডরর সমনি পড়ন। গ dark অনধকর মধ, তিি একটি রঙর স ও একটি creepy ছবিখতন। ছবির মধ মহি একটিিকটিিিিল।\n",
"\n",
"আরযন তর কহলক দমন করত, ছবিির দি কর। কিষণর মধই স একটি শবদ ভ এল। \"ভনতছ?\" সই ভয়ঙকর শবদটি আসছ। আরযন ভয় পই পিছন ফিয়, কিমন মহিসছ, স অপ করছ।\n",
"\n",
"\"আমির জনয অপ করছিম,\" মহি বলল, তর গলন মখ থর হচ। \"এটি একটি দলর রত।\"\n",
"\n",
"আরযন দইল, কি অদত আওয়জ বর হতগল। \"তিরব, করণ তি আমর দলগ দির ন।”\n",
"\n",
"\"মহির কি হয়? আপন এতিৎকর করছন? তহলি হব?” আরযন তর কহল ও ভয়র সধ করতগল।\n",
"\n",
"এই সময়, বিল সক পরিিত কর অনয ভ আসতগল। \"আমর আজ রর জনয মজ করত এসি, তি আমর সঙগ দি!\" ত একসঙইতগল, ভতগিবনত করর জনয।\n",
"\n",
"আরযন শই ভত ও চিিত হয়ল, কি কথপকথন চলত চলত, মহির মখ পরতির বিত হতগল এব আতিির কথনতনতর খশমজ বল।\n",
"\n",
"“যদিসতর, তি আমর দলরহণযয হব!” ত গল করিৎকর কর উঠল। তর মর হির সই আতঙক যন পরতিির মজয় পরিণত হল।\n",
"\n",
"খর মধ ভয়বহত চরমগল। আরযন এবর নতন বনর ভয এটি পরিণত হল। অবশ, ত উপলবি করল য ভয় ও হির মবনর আসল রসদ লি আছ। \n",
"\n",
"পরধন চরিরটি তখন বঝতরল য এই অদত ভ পরির মধির সঙগবদধত কত বিির হত। প। দল আতঙক এবির মিরণির আতমবি ও আননর অনি পরিণ কর। \n",
"\n",
"নতন বন মন আনজ করত, কখন কখন ভয় কি রসিকত এব আননর একটি নতন পরসঙগ হয় উঠত। আরযন সই রর অভিঞতিবন সমরণখব, যি এব ভয়র পতবত গড়র সগ পল।\n",
"\n",
"Claude:\n",
"After 2 iterations, this is the critique for the provided story - \n",
"\n",
"ভল। পরদতত কিশ কি উননযর সচন। বিষ কর চরিরটির বিিত পরিচয, ভ পরির অনরবশ ও চরিরগির মধযকর সঘরষ ও ডলগ আরও উননত হয। কির শ চরিরটির অভিঞত ও শি আরও গভরতভ কর। কল মিি, এটি একটি হরর কমি রচন।\n",
"\n",
"GPT:\n",
"# ভডর আতঙিত অতিি\n",
"\n",
"বনগর একটিরনির বি, আরযন, একজন করমঠ ও সহসবক, সদযই তর কলজ জবন শষ কর নতন অপরত শহর এস। নতন বনর খ, স শহরর বিিন অ, কির মধ ভয়র পরতি এক বিষ আকরষণ রয়। শ, শহরর বিিন সিিন ধরনর অদত ঘটনর কথ। একটি মজর কথ হল, সর মধ ঘটনর সনন দি।\n",
"\n",
"একদিন, তিি একটি অদত হন, য শহরর প অবসিত এবশ পরন ও বিল। হর পরিশ ছিল গ dark অনধক। তিি একটিডরর সমন এসন, স একটি এব একটি creepy ছবিয়। ছবির মহির হিিিল ভর মত।\n",
"\n",
"আরযন তর কহলক দমন করত, ছবিির দি কর। হঠৎ, স একটি শবদ ভ আস, \"ভনতছ?\" বিত কথন সর জবন প। তিিিছন ফিখতন য মহির দিিসছ। \n",
"\n",
"\"আমির জনয অপ করছিম,\" মহি গমরভ বলল, তর ভয়র আওয়জসহ। \"এটি একটি দলর রত।\"\n",
"\n",
"আরযন ভয়র সর চ করলও, স একিক ভি হযল। \"তিরব, করণ তি আমর দলগ দির ন।” মহির মর বিি আরও ভযকর লগত করল।\n",
"\n",
"\"মহির কি হয়? আপন এতিৎকর করছন? তহলি হব?” আরযন ভবছিল, তর সরণ জবনর এই অবক অনিললগছ।\n",
"\n",
"এই সময়, বিল সক পরিিত সদশ ভতরির হয়ল। \"আমর আজ রর জনয মজ করত এসি, তি আমর সঙগ দি!\" ত একসঙি বলল, এক ভ পরির রসিকতর আযজন করত।\n",
"\n",
"সবলল কথপকথন চলত চলত, আরযনর উপর থ ভয় কি এক অদত অভিঞত হয়। হর ইশয় ভ ওঠ, একর পর এক অদত ঘটন ধর। আরযন বঝতরল, তর কথনতনতিসন একটি অভতপব আননর মধরবিত হত কর।\n",
"\n",
"\"হসলি আমর দলক! আমর সঙশগরহণ কর!\" ত গল করিৎকর ত। আরযন অবশর পণবনত হি পরিশকণবনত কর।\n",
"\n",
"খর মধ ভয়বহত চরময়, কি আতিির সঙ সময় কিি আরও একবর বঝত ভয় এবির মধবনর আসল উপন লি আছ। \n",
"\n",
"আরযন আর উপলবি কর, অদত ভ পরির মধই হির বিদনর আসল আননদ ল। তিিই ভয এব আননর সিিিন, যম, বনব এবর সঙ মজর ঘনিঠতি কর। এটির জবন পরিবরতন করয় এবই রর অভিঞত একটি নতন দিচতিয়।\n",
"\n",
"Claude:\n",
"After 3 iterations, this is the critique for the provided story - \n",
"\n",
"The provided story is an excellent horror comedy piece in Bengali. No major areas of improvement are noted. The story has a well-developed protagonist, an engaging haunted setting, an effective blend of horror and humor, and a meaningful takeaway for the main character. Overall, it is a well-crafted story that successfully combines the horror and comedy genres.\n",
"\n"
]
}
],
"source": [
"view = gr.Interface(\n",
" fn=Write_Me,\n",
" inputs=[gr.Dropdown([\"English\",\"Bengali\",\"Hindi\",\"French\",\"Spanish\"],label = \"Language\"),\n",
" gr.Dropdown([\"Romantic\",\"Horror\",\"Comedy\",\"Romantic Comedy\",\"Horror Comedy\"],label = \"Genre\"),\n",
" gr.Textbox(label=\"Iterations:\", lines=1),\n",
" gr.Textbox(label=\"Remarks:\", lines=1)],\n",
" outputs=[gr.Markdown(label=\"Short Story:\"),\n",
" gr.Textbox(label=\"Critique:\", lines=8)],\n",
" flagging_mode=\"never\")\n",
"view.launch(inbrowser=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0dabafa2-089a-4e65-a6cc-19f7c19af59a",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "3c8a1c54-0344-4911-867a-3143aee0e7f0",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "5171fecb-1037-4806-b0ae-c23e8578c667",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading…
Cancel
Save