Browse Source

update udo's main branch

pull/150/head
udomai 3 months ago
parent
commit
c3e92f9720
  1. 3
      .gitignore
  2. 2
      udo/w1d1/beautifulSoupOnly.ipynb
  3. 115
      udo/w2d5/TravelAgent.ipynb

3
.gitignore vendored

@ -182,3 +182,6 @@ products_vectorstore/
# ignore optimized C++ code from being checked into repo # ignore optimized C++ code from being checked into repo
week4/optimized week4/optimized
week4/simple week4/simple
# ignore my stuff
udo

2
udo/w1d1/beautifulSoupOnly.ipynb

@ -66,7 +66,7 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"if(result == normal):\n", "if(result == normal):\n",
" print(\"No change.\")\n", " print(\"No change, but stay hopeful! It won't be much longer.\")\n",
"else:\n", "else:\n",
" print(\"CHECK THE WEBSITE NOW!\")" " print(\"CHECK THE WEBSITE NOW!\")"
] ]

115
udo/w2d5/TravelAgent.ipynb

@ -10,8 +10,8 @@
"- [x] get some extra **Python practice**\n", "- [x] get some extra **Python practice**\n",
"- [x] get lots of **tool practice**\n", "- [x] get lots of **tool practice**\n",
"- [x] increase your **Gradio proficiency**\n", "- [x] increase your **Gradio proficiency**\n",
"- [ ] try **picture output** (on command only!)\n", "- [x] try **picture output** (on command only!)\n",
"- [ ] try **audio output** (on command only?)\n", "- [x] try **audio output** (on command only?)\n",
"- [ ] try **audio input?** (most importantly, do anything you saw in the video; the rest is nice-to-have)\n", "- [ ] try **audio input?** (most importantly, do anything you saw in the video; the rest is nice-to-have)\n",
"_Extra: delve into Claude's function calling documentation (can be left for later)_" "_Extra: delve into Claude's function calling documentation (can be left for later)_"
] ]
@ -29,7 +29,11 @@
"from openai import OpenAI\n", "from openai import OpenAI\n",
"import gradio as gr\n", "import gradio as gr\n",
"import random\n", "import random\n",
"import re" "import re\n",
"import base64\n",
"from io import BytesIO\n",
"from PIL import Image\n",
"from IPython.display import Audio, display"
] ]
}, },
{ {
@ -60,7 +64,9 @@
"source": [ "source": [
"system_message = \"You are a helpful assistant for an Airline called FlightAI. \"\n", "system_message = \"You are a helpful assistant for an Airline called FlightAI. \"\n",
"system_message += \"Give short, courteous answers, no more than 1 sentence. \"\n", "system_message += \"Give short, courteous answers, no more than 1 sentence. \"\n",
"system_message += \"Always be accurate. If you don't know the answer, say so. \"" "system_message += \"Always be accurate. If you don't know the answer, say so. \"\n",
"system_message += \"You can book flights directly. \"\n",
"system_message += \"You can generate beautiful artistic renditions of the cities we fly to.\""
] ]
}, },
{ {
@ -107,10 +113,36 @@
"\n", "\n",
"def check_code(code):\n", "def check_code(code):\n",
" valid = \"valid\" if re.match(\"^[0123456789BCDFXYZ]{2}[012346789HIJKLMNOPQRS]{2}[0123456789GHIJKLMNUOP]{2}$\", code) != None else \"not valid\"\n", " valid = \"valid\" if re.match(\"^[0123456789BCDFXYZ]{2}[012346789HIJKLMNOPQRS]{2}[0123456789GHIJKLMNUOP]{2}$\", code) != None else \"not valid\"\n",
" println(f\"Code checker called for code {code}, which is {valid}.\")\n", " print(f\"Code checker called for code {code}, which is {valid}.\")\n",
" return re.match(\"^[0123456789BCDFXYZ]{2}[012346789HIJKLMNOPQRS]{2}[0123456789GHIJKLMNUOP]{2}$\", code) != None" " return re.match(\"^[0123456789BCDFXYZ]{2}[012346789HIJKLMNOPQRS]{2}[0123456789GHIJKLMNUOP]{2}$\", code) != None"
] ]
}, },
{
"cell_type": "code",
"execution_count": null,
"id": "e1d1b1c2-089c-41e5-b1bd-900632271093",
"metadata": {},
"outputs": [],
"source": [
"# make a nice preview of the travel destination\n",
"\n",
"def artist(city):\n",
" image_response = openai.images.generate(\n",
" model=\"dall-e-3\",\n",
" prompt=f\"Make an image in the style of a vibrant, artistically filtered photo that is a collage of the best sights and views in {city}.\",\n",
" size=\"1024x1024\",\n",
" n=1,\n",
" response_format=\"b64_json\",\n",
" )\n",
" image_base64 = image_response.data[0].b64_json\n",
" image_data = base64.b64decode(image_base64)\n",
" img = Image.open(BytesIO(image_data))\n",
"\n",
" img.save(\"img001.png\") #make them 4 cents count! .save is from PIL library, btw\n",
" \n",
" return img"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
@ -160,6 +192,30 @@
"}" "}"
] ]
}, },
{
"cell_type": "code",
"execution_count": null,
"id": "cc365d87-fed2-41ff-9232-850fdce1cff2",
"metadata": {},
"outputs": [],
"source": [
"artist_function = {\n",
" \"name\": \"artist\",\n",
" \"description\": \"Call this whenever you need to generate a picture, photo, or graphic impression of a city.\",\n",
" \"parameters\": {\n",
" \"type\": \"object\",\n",
" \"properties\": {\n",
" \"city\": {\n",
" \"type\": \"string\",\n",
" \"description\": \"The city of which an image is to be generated\",\n",
" },\n",
" },\n",
" \"required\": [\"city\"],\n",
" \"additionalProperties\": False\n",
" }\n",
"}"
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
@ -194,7 +250,7 @@
"source": [ "source": [
"# List of tools:\n", "# List of tools:\n",
"\n", "\n",
"tools = [{\"type\": \"function\", \"function\": price_function}, {\"type\": \"function\", \"function\": booking_function}, {\"type\": \"function\", \"function\": codecheck_function}]" "tools = [{\"type\": \"function\", \"function\": price_function}, {\"type\": \"function\", \"function\": booking_function}, {\"type\": \"function\", \"function\": codecheck_function}, {\"type\": \"function\", \"function\": artist_function}]"
] ]
}, },
{ {
@ -211,13 +267,17 @@
" \n", " \n",
" if response.choices[0].finish_reason==\"tool_calls\":\n", " if response.choices[0].finish_reason==\"tool_calls\":\n",
" message = response.choices[0].message\n", " message = response.choices[0].message\n",
" responses = handle_tool_call(message)\n", " responses = handle_tool_call(message)[0]\n",
" image = handle_tool_call(message)[1]\n",
" messages.append(message)\n", " messages.append(message)\n",
" for response in responses:\n", " for response in responses:\n",
" messages.append(response)\n", " messages.append(response)\n",
" response = openai.chat.completions.create(model=MODEL, messages=messages)\n", " response = openai.chat.completions.create(model=MODEL, messages=messages)\n",
" \n", " \n",
" reply = response.choices[0].message.content\n", " reply = response.choices[0].message.content\n",
"\n",
" #talker(reply) #current cost: $0.015 per 1000 characters (not tokens!)\n",
" \n",
" history += [{\"role\": \"assistant\", \"content\": reply}]\n", " history += [{\"role\": \"assistant\", \"content\": reply}]\n",
" \n", " \n",
" return history, image" " return history, image"
@ -232,6 +292,8 @@
"source": [ "source": [
"def handle_tool_call(message):\n", "def handle_tool_call(message):\n",
" responses = []\n", " responses = []\n",
" image = None\n",
" \n",
" for tool_call in message.tool_calls:\n", " for tool_call in message.tool_calls:\n",
" arguments = json.loads(tool_call.function.arguments)\n", " arguments = json.loads(tool_call.function.arguments)\n",
" indata = arguments[list(arguments.keys())[0]] # works for now because we only have one argument in each of our functions\n", " indata = arguments[list(arguments.keys())[0]] # works for now because we only have one argument in each of our functions\n",
@ -240,21 +302,49 @@
" outdata = get_ticket_price(indata)\n", " outdata = get_ticket_price(indata)\n",
" input_name = \"destination city\"\n", " input_name = \"destination city\"\n",
" output_name = \"price\"\n", " output_name = \"price\"\n",
" elif function_name == 'book_travel':\n", " elif function_name == 'book_flight':\n",
" outdata = book_flight(indata)\n", " outdata = book_flight(indata)\n",
" input_name = \"destination city\"\n", " input_name = \"destination city\"\n",
" output_name = \"booking code\"\n", " output_name = \"booking code\"\n",
" else:\n", " elif function_name == \"check_code\":\n",
" outdata = check_code(indata)\n", " outdata = check_code(indata)\n",
" input_name = \"booking code\"\n", " input_name = \"booking code\"\n",
" output_name = \"validity\"\n", " output_name = \"validity\"\n",
" \n", " elif function_name == \"artist\":\n",
" image = artist(indata)\n",
" outdata = f\"artistic rendition of {indata}\"\n",
" input_name = \"city\"\n",
" output_name = \"image\"\n",
"\n",
" responses.append({\n", " responses.append({\n",
" \"role\": \"tool\",\n", " \"role\": \"tool\",\n",
" \"content\": json.dumps({input_name: indata, output_name: outdata}),\n", " \"content\": json.dumps({input_name: indata, output_name: outdata}),\n",
" \"tool_call_id\": tool_call.id\n", " \"tool_call_id\": tool_call.id\n",
" })\n", " })\n",
" return responses" "\n",
" return responses, image"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "505b585e-e9f9-4326-8455-184398bc82d1",
"metadata": {},
"outputs": [],
"source": [
"def talker(message):\n",
" response = openai.audio.speech.create(\n",
" model=\"tts-1\",\n",
" voice=\"onyx\",\n",
" input=message)\n",
"\n",
" audio_stream = BytesIO(response.content)\n",
" output_filename = \"output_audio.mp3\"\n",
" with open(output_filename, \"wb\") as f:\n",
" f.write(audio_stream.read())\n",
"\n",
" # Play the generated audio\n",
" display(Audio(output_filename, autoplay=True))"
] ]
}, },
{ {
@ -264,8 +354,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"# More involved Gradio code as we're not using the preset Chat interface!\n", "## Gradio\n",
"# Passing in inbrowser=True in the last line will cause a Gradio window to pop up immediately.\n",
"\n", "\n",
"with gr.Blocks() as ui:\n", "with gr.Blocks() as ui:\n",
" with gr.Row():\n", " with gr.Row():\n",

Loading…
Cancel
Save