Merge branch 'community-contributions-branch' of https://github.com/pradeep1955/llm_engineering into community-contributions-branch
"submit triangular conversations"
This commit is contained in:
654
week2/community-contributions/FlightAI-exercise.ipynb
Normal file
654
week2/community-contributions/FlightAI-exercise.ipynb
Normal file
@@ -0,0 +1,654 @@
|
||||
{
|
||||
"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": null,
|
||||
"id": "a07e7793-b8f5-44f4-aded-5562f633271a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Imports\n",
|
||||
"\n",
|
||||
"import os\n",
|
||||
"import json\n",
|
||||
"import base64\n",
|
||||
"import logging\n",
|
||||
"import gradio as gr\n",
|
||||
"from PIL import Image\n",
|
||||
"from io import BytesIO\n",
|
||||
"from openai import OpenAI\n",
|
||||
"from dotenv import load_dotenv\n",
|
||||
"from IPython.display import Audio, display"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "e879f6ae-b246-479d-8f81-94e47a9072ec",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Initialization\n",
|
||||
"logging.basicConfig(level=logging.INFO)\n",
|
||||
"load_dotenv(override=True)\n",
|
||||
"\n",
|
||||
"openai_api_key = os.getenv('OPENAI_API_KEY')\n",
|
||||
"if openai_api_key:\n",
|
||||
" logging.info(f\"OpenAI API Key exists and begins {openai_api_key[:8]}\")\n",
|
||||
"else:\n",
|
||||
" logging.error(\"OpenAI API Key not set\")\n",
|
||||
" \n",
|
||||
"MODEL = \"gpt-4o-mini\"\n",
|
||||
"openai = OpenAI()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "d4455169-9e5e-4171-92e8-6f850a06f6e3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"system_message = (\n",
|
||||
" \"You are a helpful assistant for an airline called FlightAI. \"\n",
|
||||
" \"Always respond in a short, courteous sentence. \"\n",
|
||||
" \"Provide accurate information only. \"\n",
|
||||
" \"If you don’t know something, say so clearly. \"\n",
|
||||
" \"Before booking a ticket, strictly follow this order: \"\n",
|
||||
" \"1) Check if the destination is available, \"\n",
|
||||
" \"2) Then check the ticket price, \"\n",
|
||||
" \"3) Collect all neccessary details like name, destination and date of journey, \"\n",
|
||||
" \"4) Only then proceed with the booking. \"\n",
|
||||
" \"Always use the appropriate tools or APIs for each step before confirming a booking.\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "4bab8e2c-e2b1-4421-a95b-7f1251670817",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Dummy funcs that mimic the ticket booking behaviour\n",
|
||||
"# Replace these will real funcs (that call APIs or make DB transactions) to actually book a ticket\n",
|
||||
"\n",
|
||||
"ticket_prices = {\n",
|
||||
" \"london\": \"$799\",\n",
|
||||
" \"paris\": \"$899\",\n",
|
||||
" \"tokyo\": \"$1400\",\n",
|
||||
" \"berlin\": \"$499\"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"def check_destination_availability(destination: str) -> dict:\n",
|
||||
" \"\"\"\n",
|
||||
" Check if the given destination is available in our ticketing system.\n",
|
||||
" \n",
|
||||
" Args:\n",
|
||||
" destination (str): The name of the city.\n",
|
||||
" \n",
|
||||
" Returns:\n",
|
||||
" dict: {\"available\": bool}\n",
|
||||
" \"\"\"\n",
|
||||
" logging.info(f\"Checking availability for destination: {destination}\")\n",
|
||||
" \n",
|
||||
" available = destination.lower() in ticket_prices\n",
|
||||
" return {\"available\": available}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def fetch_ticket_price(destination_city: str) -> dict:\n",
|
||||
" \"\"\"\n",
|
||||
" Retrieve the ticket price for a given city.\n",
|
||||
" \n",
|
||||
" Args:\n",
|
||||
" destination_city (str): The name of the destination city.\n",
|
||||
" \n",
|
||||
" Returns:\n",
|
||||
" dict: {\"price\": str} or {\"price\": \"Unknown\"} if not found\n",
|
||||
" \"\"\"\n",
|
||||
" logging.info(f\"Retrieving price for destination: {destination_city}\")\n",
|
||||
" \n",
|
||||
" city = destination_city.lower()\n",
|
||||
" price = ticket_prices.get(city, \"Unknown\")\n",
|
||||
" \n",
|
||||
" return {\"price\": price}\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def book_ticket(name: str, destination_city: str, journey_date: str) -> dict:\n",
|
||||
" \"\"\"\n",
|
||||
" Book a ticket to a destination city for a given user and date.\n",
|
||||
" \n",
|
||||
" Args:\n",
|
||||
" name (str): Name of the passenger.\n",
|
||||
" destination_city (str): Destination city.\n",
|
||||
" journey_date (str): Date of journey in YYYY-MM-DD format.\n",
|
||||
" \n",
|
||||
" Returns:\n",
|
||||
" dict: Booking confirmation with name, city, price, and date, or error.\n",
|
||||
" \"\"\"\n",
|
||||
" logging.info(f\"Booking ticket for {name} to {destination_city} on {journey_date}\")\n",
|
||||
" \n",
|
||||
" city = destination_city.lower()\n",
|
||||
"\n",
|
||||
" if city not in ticket_prices:\n",
|
||||
" logging.error(f\"City '{destination_city}' not found in ticket list.\")\n",
|
||||
" return {\"error\": \"Destination not found.\"}\n",
|
||||
"\n",
|
||||
" price_info = fetch_ticket_price(destination_city)\n",
|
||||
" \n",
|
||||
" return {\n",
|
||||
" \"name\": name,\n",
|
||||
" \"destination_city\": destination_city.title(),\n",
|
||||
" \"journey_date\": journey_date,\n",
|
||||
" \"price\": price_info[\"price\"]\n",
|
||||
" }\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "400f4592-2326-43f6-a921-fcd051c4f022",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"destination_availability_tool = {\n",
|
||||
" \"name\": \"check_destination_availability\",\n",
|
||||
" \"description\": \"Check if tickets are available for the given destination city before proceeding with any booking or pricing inquiry.\",\n",
|
||||
" \"parameters\": {\n",
|
||||
" \"type\": \"object\",\n",
|
||||
" \"properties\": {\n",
|
||||
" \"destination\": {\n",
|
||||
" \"type\": \"string\",\n",
|
||||
" \"description\": \"The name of the destination city to check for availability.\"\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" \"required\": [\"destination\"],\n",
|
||||
" \"additionalProperties\": False\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"ticket_price_tool = {\n",
|
||||
" \"name\": \"fetch_ticket_price\",\n",
|
||||
" \"description\": (\n",
|
||||
" \"Get the price of a return ticket to the specified destination city. \"\n",
|
||||
" \"Use this after confirming that the destination is available, especially when the customer asks for the ticket price.\"\n",
|
||||
" ),\n",
|
||||
" \"parameters\": {\n",
|
||||
" \"type\": \"object\",\n",
|
||||
" \"properties\": {\n",
|
||||
" \"destination_city\": {\n",
|
||||
" \"type\": \"string\",\n",
|
||||
" \"description\": \"The city for which the customer wants the ticket price.\"\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" \"required\": [\"destination_city\"],\n",
|
||||
" \"additionalProperties\": False\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"ticket_booking_tool = {\n",
|
||||
" \"name\": \"book_ticket\",\n",
|
||||
" \"description\": (\n",
|
||||
" \"Book a ticket for the customer to the specified destination city on the given journey date. \"\n",
|
||||
" \"Use only after availability and price have been checked.\"\n",
|
||||
" ),\n",
|
||||
" \"parameters\": {\n",
|
||||
" \"type\": \"object\",\n",
|
||||
" \"properties\": {\n",
|
||||
" \"name\": {\n",
|
||||
" \"type\": \"string\",\n",
|
||||
" \"description\": \"Full name of the person booking the ticket.\"\n",
|
||||
" },\n",
|
||||
" \"destination_city\": {\n",
|
||||
" \"type\": \"string\",\n",
|
||||
" \"description\": \"The city that the customer wants to travel to.\"\n",
|
||||
" },\n",
|
||||
" \"journey_date\": {\n",
|
||||
" \"type\": \"string\",\n",
|
||||
" \"format\": \"date\",\n",
|
||||
" \"description\": \"The journey date in YYYY-MM-DD format.\"\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" \"required\": [\"name\", \"destination_city\", \"journey_date\"],\n",
|
||||
" \"additionalProperties\": False\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"tools = [\n",
|
||||
" {\"type\": \"function\", \"function\": destination_availability_tool},\n",
|
||||
" {\"type\": \"function\", \"function\": ticket_price_tool},\n",
|
||||
" {\"type\": \"function\", \"function\": ticket_booking_tool},\n",
|
||||
"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f02c17ba-14f2-41c4-b6a2-d1397405d368",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def handle_tool_call(message):\n",
|
||||
" \"\"\"\n",
|
||||
" Handles a single OpenAI tool call message and returns both the result\n",
|
||||
" and a formatted tool response dictionary.\n",
|
||||
" \n",
|
||||
" Args:\n",
|
||||
" message (object): An OpenAI message containing a tool call.\n",
|
||||
" \n",
|
||||
" Returns:\n",
|
||||
" tuple: (result_dict, response_dict)\n",
|
||||
" \"\"\"\n",
|
||||
" tool_call = message.tool_calls[0]\n",
|
||||
" function_name = tool_call.function.name\n",
|
||||
" arguments = json.loads(tool_call.function.arguments)\n",
|
||||
"\n",
|
||||
" result = None\n",
|
||||
"\n",
|
||||
" logging.info(f\"Tool call received: {function_name} with arguments: {arguments}\")\n",
|
||||
"\n",
|
||||
" if function_name == \"check_destination_availability\":\n",
|
||||
" result = check_destination_availability(**arguments)\n",
|
||||
"\n",
|
||||
" elif function_name == \"fetch_ticket_price\":\n",
|
||||
" city = arguments.get(\"destination_city\")\n",
|
||||
" price_info = fetch_ticket_price(city)\n",
|
||||
" result = {\"destination_city\": city, \"price\": price_info[\"price\"]}\n",
|
||||
"\n",
|
||||
" elif function_name == \"book_ticket\":\n",
|
||||
" result = book_ticket(**arguments)\n",
|
||||
"\n",
|
||||
" else:\n",
|
||||
" logging.warning(\"Unrecognized tool function: %s\", function_name)\n",
|
||||
" result = {\"error\": f\"Unknown function '{function_name}'\"}\n",
|
||||
"\n",
|
||||
" response = {\n",
|
||||
" \"role\": \"tool\",\n",
|
||||
" \"tool_call_id\": tool_call.id,\n",
|
||||
" \"content\": json.dumps(result)\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" return result, response"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "72c1a9e7-186c-4218-9edc-01814baec431",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def artist(city: str, style: str = \"vibrant pop-art\", size: str = \"1024x1024\") -> Image.Image:\n",
|
||||
" \"\"\"\n",
|
||||
" Generates a city-themed vacation image using DALL·E.\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" city (str): Name of the city to visualize.\n",
|
||||
" style (str): Artistic style for the image prompt.\n",
|
||||
" size (str): Image resolution (e.g., \"1024x1024\").\n",
|
||||
"\n",
|
||||
" Returns:\n",
|
||||
" Image.Image: A PIL Image object representing the generated image.\n",
|
||||
"\n",
|
||||
" Raises:\n",
|
||||
" ValueError: If city name is empty.\n",
|
||||
" RuntimeError: If image generation fails.\n",
|
||||
" \"\"\"\n",
|
||||
" if not city.strip():\n",
|
||||
" raise ValueError(\"City name cannot be empty.\")\n",
|
||||
"\n",
|
||||
" prompt = (\n",
|
||||
" f\"An image representing a vacation in {city}, \"\n",
|
||||
" f\"showing iconic tourist attractions, cultural elements, and everything unique about {city}, \"\n",
|
||||
" f\"rendered in a {style} style.\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" logging.info(\"Generating image for city: %s with style: %s\", city, style)\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" response = openai.images.generate(\n",
|
||||
" model=\"dall-e-3\",\n",
|
||||
" prompt=prompt,\n",
|
||||
" size=size,\n",
|
||||
" n=1,\n",
|
||||
" response_format=\"b64_json\",\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" image_base64 = response.data[0].b64_json\n",
|
||||
" image_data = base64.b64decode(image_base64)\n",
|
||||
" logging.info(\"Image generation successful for %s\", city)\n",
|
||||
"\n",
|
||||
" return Image.open(BytesIO(image_data))\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" logging.error(\"Failed to generate image for city '%s': %s\", city, str(e))\n",
|
||||
" raise RuntimeError(f\"Image generation failed for city '{city}'\") from e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "fdf7c091-6c68-4af6-8197-c1456b36cedf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def talker(message: str, output_filename: str = \"output_audio.mp3\", autoplay: bool = True) -> None:\n",
|
||||
" \"\"\"\n",
|
||||
" Converts a text message into speech using OpenAI TTS and plays the audio.\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" message (str): The text to convert to speech.\n",
|
||||
" output_filename (str): The filename to save the generated audio.\n",
|
||||
" autoplay (bool): Whether to autoplay the audio in the notebook.\n",
|
||||
"\n",
|
||||
" Raises:\n",
|
||||
" ValueError: If the message is empty.\n",
|
||||
" RuntimeError: If the audio generation fails.\n",
|
||||
" \"\"\"\n",
|
||||
" if not message.strip():\n",
|
||||
" raise ValueError(\"Message cannot be empty.\")\n",
|
||||
"\n",
|
||||
" logging.info(\"Generating speech for message: %s\", message)\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" response = openai.audio.speech.create(\n",
|
||||
" model=\"tts-1\",\n",
|
||||
" voice=\"alloy\",\n",
|
||||
" input=message\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" with open(output_filename, \"wb\") as f:\n",
|
||||
" f.write(response.content)\n",
|
||||
"\n",
|
||||
" logging.info(\"Audio written to: %s\", output_filename)\n",
|
||||
"\n",
|
||||
" if autoplay:\n",
|
||||
" display(Audio(output_filename, autoplay=True))\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" logging.error(\"Failed to generate or play audio: %s\", str(e))\n",
|
||||
" raise RuntimeError(\"Text-to-speech generation failed.\") from e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "54568b4a-be8d-47a1-b924-03acdafef70e",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def translate(message, language):\n",
|
||||
" \"\"\"\n",
|
||||
" Translates the given text into the specified language using OpenAI Chat API.\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" message (str): The text to be translated.\n",
|
||||
" language (str): Target language for translation (e.g., 'French', 'Japanese').\n",
|
||||
"\n",
|
||||
" Returns:\n",
|
||||
" str: Translated text.\n",
|
||||
"\n",
|
||||
" Raises:\n",
|
||||
" ValueError: If input message or language is empty.\n",
|
||||
" RuntimeError: If translation fails due to API or other issues.\n",
|
||||
" \"\"\"\n",
|
||||
" if not message.strip():\n",
|
||||
" raise ValueError(\"Input message cannot be empty.\")\n",
|
||||
" if not language.strip():\n",
|
||||
" raise ValueError(\"Target language cannot be empty.\")\n",
|
||||
"\n",
|
||||
" logging.info(\"Translating to %s: %s\", language, message)\n",
|
||||
"\n",
|
||||
" messages = [\n",
|
||||
" {\"role\": \"system\", \"content\": f\"You are a translation assistant. Translate everything the user says to {language}.\"},\n",
|
||||
" {\"role\": \"user\", \"content\": message}\n",
|
||||
" ]\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" response = openai.chat.completions.create(\n",
|
||||
" model=MODEL,\n",
|
||||
" messages=messages\n",
|
||||
" )\n",
|
||||
" translated = response.choices[0].message.content.strip()\n",
|
||||
" logging.info(\"Translation successful.\")\n",
|
||||
" return translated\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" logging.error(\"Translation failed: %s\", str(e))\n",
|
||||
" raise RuntimeError(\"Failed to translate message.\") from e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "8e6cf470-8ea0-43b2-bbcc-53c2432feb0d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def transcribe_audio(audio_path):\n",
|
||||
" \"\"\"\n",
|
||||
" Transcribes an audio file using OpenAI's Whisper model.\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" audio_path (str): Path to the audio file (e.g., .mp3, .wav).\n",
|
||||
" model (str): OpenAI model for transcription (default: 'whisper-1').\n",
|
||||
"\n",
|
||||
" Returns:\n",
|
||||
" str: Transcribed text from the audio file.\n",
|
||||
"\n",
|
||||
" Raises:\n",
|
||||
" ValueError: If the path is invalid or the file does not exist.\n",
|
||||
" RuntimeError: If the transcription fails.\n",
|
||||
" \"\"\"\n",
|
||||
" if not audio_path or not os.path.exists(audio_path):\n",
|
||||
" raise ValueError(\"Invalid or missing audio file path.\")\n",
|
||||
"\n",
|
||||
" logging.info(\"Transcribing audio file: %s using model: whisper-1\", audio_path)\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" with open(audio_path, \"rb\") as f:\n",
|
||||
" response = openai.audio.transcriptions.create(\n",
|
||||
" model=\"whisper-1\",\n",
|
||||
" file=f\n",
|
||||
" )\n",
|
||||
" transcript = response.text.strip()\n",
|
||||
" logging.info(\"Transcription successful.\")\n",
|
||||
" return transcript\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" logging.error(\"Transcription failed: %s\", str(e))\n",
|
||||
" raise RuntimeError(\"Failed to transcribe audio.\") from e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "3489656e-0f08-4d41-94b1-d902c93ca164",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def chat(history: list, language: str, translated_history: list, speaking_language: str) -> tuple:\n",
|
||||
" \"\"\"\n",
|
||||
" Handles a chat interaction including tool calls, image generation, translation, and TTS playback.\n",
|
||||
"\n",
|
||||
" Args:\n",
|
||||
" history (list): List of previous conversation messages.\n",
|
||||
" language (str): Target language for translation and TTS.\n",
|
||||
"\n",
|
||||
" Returns:\n",
|
||||
" tuple: (updated history list, generated image if any, translated response string)\n",
|
||||
" \"\"\"\n",
|
||||
" messages = [{\"role\": \"system\", \"content\": system_message}] + history\n",
|
||||
" image = None\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" # Initial assistant response\n",
|
||||
" response = openai.chat.completions.create(model=MODEL, messages=messages, tools=tools)\n",
|
||||
" choice = response.choices[0]\n",
|
||||
"\n",
|
||||
" # Handle tool calls if triggered\n",
|
||||
" if choice.finish_reason == \"tool_calls\":\n",
|
||||
" message = choice.message\n",
|
||||
" result, tool_response = handle_tool_call(message)\n",
|
||||
"\n",
|
||||
" # Append tool-related messages\n",
|
||||
" messages.append(message)\n",
|
||||
" messages.append(tool_response)\n",
|
||||
" logging.info(\"Tool call result: %s\", result)\n",
|
||||
"\n",
|
||||
" # Generate image if a booking was completed\n",
|
||||
" if message.tool_calls[0].function.name == \"book_ticket\" and \"destination_city\" in result:\n",
|
||||
" image = artist(result[\"destination_city\"])\n",
|
||||
"\n",
|
||||
" # Get final assistant response after tool execution\n",
|
||||
" response = openai.chat.completions.create(model=MODEL, messages=messages)\n",
|
||||
" choice = response.choices[0]\n",
|
||||
"\n",
|
||||
" reply = choice.message.content.strip()\n",
|
||||
" history.append({\"role\": \"assistant\", \"content\": reply})\n",
|
||||
"\n",
|
||||
" # Translate and speak the reply\n",
|
||||
" translated_reply = translate(reply, language)\n",
|
||||
" translated_history.append({\"role\": \"assistant\", \"content\": translated_reply})\n",
|
||||
"\n",
|
||||
" if speaking_language == \"English\":\n",
|
||||
" talker(reply)\n",
|
||||
" else:\n",
|
||||
" talker(translated_reply)\n",
|
||||
"\n",
|
||||
" return history, image, translated_history\n",
|
||||
"\n",
|
||||
" except Exception as e:\n",
|
||||
" logging.error(\"Chat processing failed: %s\", str(e))\n",
|
||||
" raise RuntimeError(\"Failed to complete chat interaction.\") from e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f76acc68-726e-457f-88ab-99da75debde5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"force_dark_mode = \"\"\"\n",
|
||||
"function refresh() {\n",
|
||||
" const url = new URL(window.location);\n",
|
||||
" if (url.searchParams.get('__theme') !== 'dark') {\n",
|
||||
" url.searchParams.set('__theme', 'dark');\n",
|
||||
" window.location.href = url.href;\n",
|
||||
" }\n",
|
||||
"}\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"with gr.Blocks(js=force_dark_mode) as ui:\n",
|
||||
" with gr.Row():\n",
|
||||
" gr.Markdown(\"### FlightAI Chat with Translation\")\n",
|
||||
"\n",
|
||||
" with gr.Row():\n",
|
||||
" lang_dropdown = gr.Dropdown(\n",
|
||||
" choices=[\"Spanish\", \"French\", \"German\", \"Japanese\", \"Hindi\"],\n",
|
||||
" value=\"Spanish\",\n",
|
||||
" label=\"Translate To\"\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" speak_dropdown = gr.Dropdown(\n",
|
||||
" choices=[\"English\", \"Selected Language\"],\n",
|
||||
" value=\"English\",\n",
|
||||
" label=\"Speak out in\"\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" with gr.Row():\n",
|
||||
" chatbot = gr.Chatbot(height=500, type=\"messages\", label=\"Chat History\")\n",
|
||||
" translated_chatbot = gr.Chatbot(height=500, type=\"messages\", label=\"Translated Chat\")\n",
|
||||
" image_output = gr.Image(height=500)\n",
|
||||
"\n",
|
||||
" with gr.Row():\n",
|
||||
" entry = gr.Textbox(label=\"Chat with our AI Assistant:\")\n",
|
||||
" audio_input = gr.Audio(sources=\"microphone\", type=\"filepath\", label=\"Or speak to the assistant\")\n",
|
||||
"\n",
|
||||
" with gr.Row():\n",
|
||||
" clear = gr.Button(\"Clear\")\n",
|
||||
"\n",
|
||||
" def do_entry(message, history, audio, translated_history, language):\n",
|
||||
" if audio:\n",
|
||||
" message = transcribe_audio(audio)\n",
|
||||
"\n",
|
||||
" if message:\n",
|
||||
" history += [{\"role\": \"user\", \"content\": message}]\n",
|
||||
" translated_history += [{\"role\": \"user\", \"content\": translate(message, language)}]\n",
|
||||
" return \"\", history, None, translated_history\n",
|
||||
"\n",
|
||||
" entry.submit(\n",
|
||||
" do_entry,\n",
|
||||
" inputs=[entry, chatbot, audio_input, translated_chatbot, lang_dropdown],\n",
|
||||
" outputs=[entry, chatbot, audio_input, translated_chatbot]\n",
|
||||
" ).then(\n",
|
||||
" chat,\n",
|
||||
" inputs=[chatbot, lang_dropdown, translated_chatbot, speak_dropdown],\n",
|
||||
" outputs=[chatbot, image_output, translated_chatbot]\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" audio_input.change(\n",
|
||||
" do_entry,\n",
|
||||
" inputs=[entry, chatbot, audio_input, translated_chatbot, lang_dropdown],\n",
|
||||
" outputs=[entry, chatbot, audio_input, translated_chatbot]\n",
|
||||
" ).then(\n",
|
||||
" chat,\n",
|
||||
" inputs=[chatbot, lang_dropdown, translated_chatbot, speak_dropdown],\n",
|
||||
" outputs=[chatbot, image_output, translated_chatbot]\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" clear.click(lambda: [\"\", [], None, [], None], inputs=None, outputs=[entry, chatbot, audio_input, translated_chatbot, image_output], queue=False)\n",
|
||||
"\n",
|
||||
"ui.launch(inbrowser=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "58f97435-fa0d-45f7-b02f-4ac5f4901c53",
|
||||
"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.10.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
344
week2/community-contributions/clinic_booking_bot.ipynb
Normal file
344
week2/community-contributions/clinic_booking_bot.ipynb
Normal file
@@ -0,0 +1,344 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 170,
|
||||
"id": "a1aa1b43-7a47-4aca-ae5f-94a9d4ba2d89",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"## Clinic Booking Bot\n",
|
||||
"\n",
|
||||
"##Easily book your clinic visit – available only on weekdays between **14:00 and 15:00**. \n",
|
||||
"##Speak or type, and get instant confirmation.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 171,
|
||||
"id": "fe798c6a-f8da-46aa-8c0e-9d2623def3d2",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# import library\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",
|
||||
"from datetime import date\n",
|
||||
"from PIL import Image, ImageDraw, ImageFont\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 172,
|
||||
"id": "0ad4e526-e95d-4e70-9faa-b4236b105dd5",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"OpenAI API Key exists and begins sk-proj-\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Save keys\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",
|
||||
"MODEL = \"gpt-4o-mini\"\n",
|
||||
"openai = OpenAI()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 173,
|
||||
"id": "ae95308e-0002-4017-9f2c-fcb1ddb248fa",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# --- CONFIG ---\n",
|
||||
"BOOKING_START = 14\n",
|
||||
"BOOKING_END = 15\n",
|
||||
"WEEKDAYS = [\"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\"]\n",
|
||||
"PHONE = \"010-1234567\"\n",
|
||||
"confirmed_bookings = []\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 174,
|
||||
"id": "e21b0fd0-4cda-4938-8867-dc2c6e7af4b1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# --- TTS ---\n",
|
||||
"def generate_tts(text, voice=\"fable\", filename=\"output.mp3\"):\n",
|
||||
" response = openai.audio.speech.create(\n",
|
||||
" model=\"tts-1\",\n",
|
||||
" voice=\"fable\",\n",
|
||||
" input=text\n",
|
||||
" )\n",
|
||||
" with open(filename, \"wb\") as f:\n",
|
||||
" f.write(response.content)\n",
|
||||
" return filename"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 175,
|
||||
"id": "e28a5c3b-bd01-4845-a41e-87823f6bb078",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# --- Translate Booking Confirmation ---\n",
|
||||
"def translate_text(text, target_language=\"nl\"):\n",
|
||||
" prompt = f\"Translate this message to {target_language}:\\n{text}\"\n",
|
||||
" response = openai.chat.completions.create(\n",
|
||||
" model=\"gpt-4\",\n",
|
||||
" messages=[\n",
|
||||
" {\"role\": \"system\", \"content\": \"You are a helpful translator.\"},\n",
|
||||
" {\"role\": \"user\", \"content\": prompt}\n",
|
||||
" ]\n",
|
||||
" )\n",
|
||||
" return response.choices[0].message.content.strip()\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 176,
|
||||
"id": "8ed57cc9-7d54-4a5d-831b-0efcc5b7a7a9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# --- Booking Logic ---\n",
|
||||
"def book_appointment(name, time_str):\n",
|
||||
" try:\n",
|
||||
" booking_time = datetime.strptime(time_str, \"%H:%M\")\n",
|
||||
" except ValueError:\n",
|
||||
" return \"Invalid time format. Use HH:MM.\", None, None\n",
|
||||
"\n",
|
||||
" hour = booking_time.hour\n",
|
||||
" weekday = datetime.today().strftime(\"%A\")\n",
|
||||
"\n",
|
||||
" if weekday not in WEEKDAYS:\n",
|
||||
" response = \"Bookings are only available on weekdays.\"\n",
|
||||
" elif BOOKING_START <= hour < BOOKING_END:\n",
|
||||
" confirmation = f\"Booking confirmed for {name} at {time_str}.\"\n",
|
||||
" confirmed_bookings.append((name, time_str))\n",
|
||||
" translated = translate_text(confirmation)\n",
|
||||
" audio = generate_tts(translated)\n",
|
||||
" image = generate_booking_image(name, time_str)\n",
|
||||
" return translated, audio, image\n",
|
||||
" else:\n",
|
||||
" response = \"Sorry, bookings are only accepted between 14:00 and 15:00 on weekdays.\"\n",
|
||||
" translated = translate_text(response)\n",
|
||||
" audio = generate_tts(translated)\n",
|
||||
" return translated, audio, None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 177,
|
||||
"id": "19b52115-f0f3-4d63-a463-886163d4cfd1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# --- Booking Card ---\n",
|
||||
"def generate_booking_image(name, time_str):\n",
|
||||
" img = Image.new(\"RGB\", (500, 250), color=\"white\")\n",
|
||||
" draw = ImageDraw.Draw(img)\n",
|
||||
" msg = f\"\\u2705 Booking Confirmed\\nName: {name}\\nTime: {time_str}\"\n",
|
||||
" draw.text((50, 100), msg, fill=\"black\")\n",
|
||||
" return img"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 178,
|
||||
"id": "2c446b6c-d410-4ba1-b0c7-c475e5259ff5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# --- Voice Booking ---\n",
|
||||
"def voice_booking(audio_path, name):\n",
|
||||
" with open(audio_path, \"rb\") as f:\n",
|
||||
" response = openai.audio.transcriptions.create(model=\"whisper-1\", file=f)\n",
|
||||
" transcription = response.text.strip()\n",
|
||||
"\n",
|
||||
" system_prompt = \"\"\"\n",
|
||||
" You are a clinic assistant. Extract only the appointment time from the user's sentence in 24-hour HH:MM format.\n",
|
||||
" If no time is mentioned, respond with 'No valid time found.'\n",
|
||||
" \"\"\"\n",
|
||||
"\n",
|
||||
" response = openai.chat.completions.create(\n",
|
||||
" model=\"gpt-4\",\n",
|
||||
" messages=[\n",
|
||||
" {\"role\": \"system\", \"content\": system_prompt},\n",
|
||||
" {\"role\": \"user\", \"content\": transcription}\n",
|
||||
" ]\n",
|
||||
" )\n",
|
||||
" extracted_time = response.choices[0].message.content.strip()\n",
|
||||
"\n",
|
||||
" if \":\" in extracted_time:\n",
|
||||
" return book_appointment(name, extracted_time)\n",
|
||||
" else:\n",
|
||||
" message = \"Sorry, I couldn't understand the time. Please try again.\"\n",
|
||||
" translated = translate_text(message)\n",
|
||||
" audio_path = generate_tts(translated)\n",
|
||||
" return translated, audio_path, None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 179,
|
||||
"id": "121d2907-7fa8-4248-b2e7-83617ea66ff0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# --- Chat Bot Handler ---\n",
|
||||
"def chat_bot(messages):\n",
|
||||
" system_prompt = \"\"\"\n",
|
||||
" You are a clinic booking assistant. Your job is to:\n",
|
||||
" - Greet the patient and explain your role\n",
|
||||
" - Only assist with making appointments\n",
|
||||
" - Accept bookings only on weekdays between 14:00 and 15:00\n",
|
||||
" - Do not provide medical advice\n",
|
||||
" - Always respond with empathy and clarity\n",
|
||||
" \"\"\"\n",
|
||||
" response = openai.chat.completions.create(\n",
|
||||
" model=\"gpt-4\",\n",
|
||||
" messages=[{\"role\": \"system\", \"content\": system_prompt}] + messages\n",
|
||||
" )\n",
|
||||
" reply = response.choices[0].message.content.strip()\n",
|
||||
" audio = generate_tts(reply)\n",
|
||||
" return reply, audio"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 180,
|
||||
"id": "2427b694-8c57-40cb-b202-4a8989547925",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7898\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7898/\" 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"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Gradio interface\n",
|
||||
"with gr.Blocks(theme=gr.themes.Soft()) as demo:\n",
|
||||
" gr.Markdown(\"\"\"## 🩺 GP Booking Assistant \n",
|
||||
"Only available weekdays between **14:00 and 15:00** \n",
|
||||
"☎️ Contact: {PHONE}\n",
|
||||
"---\"\"\")\n",
|
||||
"\n",
|
||||
" name_global = gr.Textbox(label=\"Your Name\", placeholder=\"Enter your name\", interactive=True)\n",
|
||||
"\n",
|
||||
" with gr.Tab(\"💬 Chat Mode\"):\n",
|
||||
" chatbot = gr.Chatbot(label=\"Booking Chat\", type=\"messages\", height=400)\n",
|
||||
" text_input = gr.Textbox(label=\"Type your message or use your voice below\")\n",
|
||||
" audio_input = gr.Audio(type=\"filepath\", label=\"🎙️ Or speak your request\")\n",
|
||||
" chat_audio_output = gr.Audio(label=\"🔊 Assistant's Reply\", type=\"filepath\")\n",
|
||||
" send_btn = gr.Button(\"Send\")\n",
|
||||
"\n",
|
||||
" def handle_chat(user_message, chat_history):\n",
|
||||
" chat_history = chat_history or []\n",
|
||||
" chat_history.append({\"role\": \"user\", \"content\": user_message})\n",
|
||||
" reply, audio = chat_bot(chat_history)\n",
|
||||
" chat_history.append({\"role\": \"assistant\", \"content\": reply})\n",
|
||||
" return chat_history, \"\", audio\n",
|
||||
"\n",
|
||||
" def handle_audio_chat(audio_path, chat_history):\n",
|
||||
" with open(audio_path, \"rb\") as f:\n",
|
||||
" transcription = openai.audio.transcriptions.create(model=\"whisper-1\", file=f).text.strip()\n",
|
||||
" return handle_chat(transcription, chat_history)\n",
|
||||
"\n",
|
||||
" send_btn.click(handle_chat, [text_input, chatbot], [chatbot, text_input, chat_audio_output])\n",
|
||||
" text_input.submit(handle_chat, [text_input, chatbot], [chatbot, text_input, chat_audio_output])\n",
|
||||
" audio_input.change(handle_audio_chat, [audio_input, chatbot], [chatbot, text_input, chat_audio_output])\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" \n",
|
||||
" with gr.Tab(\"📝 Text Booking\"):\n",
|
||||
" time_text = gr.Textbox(label=\"Preferred Time (HH:MM)\", placeholder=\"e.g., 14:30\")\n",
|
||||
" btn_text = gr.Button(\"📅 Book via Text\")\n",
|
||||
"\n",
|
||||
" with gr.Tab(\"🎙️ Voice Booking\"):\n",
|
||||
" voice_input = gr.Audio(type=\"filepath\", label=\"Say your preferred time\")\n",
|
||||
" btn_voice = gr.Button(\"📅 Book via Voice\")\n",
|
||||
"\n",
|
||||
" output_text = gr.Textbox(label=\"Response\", interactive=False)\n",
|
||||
" output_audio = gr.Audio(label=\"Audio Reply\", type=\"filepath\")\n",
|
||||
" output_image = gr.Image(label=\"Booking Confirmation\")\n",
|
||||
"\n",
|
||||
" btn_text.click(fn=book_appointment, inputs=[name_global, time_text], outputs=[output_text, output_audio, output_image])\n",
|
||||
" btn_voice.click(fn=voice_booking, inputs=[voice_input, name_global], outputs=[output_text, output_audio, output_image])\n",
|
||||
"\n",
|
||||
" gr.Markdown(\"\"\"---\n",
|
||||
"<small>This assistant does **not** give medical advice. It only books appointments within allowed hours.</small>\n",
|
||||
"\"\"\")\n",
|
||||
"\n",
|
||||
" demo.launch()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "f359de0a-28b1-4895-b21d-91d79e494a0d",
|
||||
"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.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
||||
@@ -290,12 +290,12 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# If you have access to this, here is the reasoning model o3-mini\n",
|
||||
"# If you have access to this, here is the reasoning model o4-mini\n",
|
||||
"# This is trained to think through its response before replying\n",
|
||||
"# So it will take longer but the answer should be more reasoned - not that this helps..\n",
|
||||
"\n",
|
||||
"completion = openai.chat.completions.create(\n",
|
||||
" model='o3-mini',\n",
|
||||
" model='o4-mini',\n",
|
||||
" messages=prompts\n",
|
||||
")\n",
|
||||
"print(completion.choices[0].message.content)"
|
||||
@@ -308,12 +308,12 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Claude 3.7 Sonnet\n",
|
||||
"# Claude 4.0 Sonnet\n",
|
||||
"# API needs system message provided separately from user prompt\n",
|
||||
"# Also adding max_tokens\n",
|
||||
"\n",
|
||||
"message = claude.messages.create(\n",
|
||||
" model=\"claude-3-7-sonnet-latest\",\n",
|
||||
" model=\"claude-sonnet-4-20250514\",\n",
|
||||
" max_tokens=200,\n",
|
||||
" temperature=0.7,\n",
|
||||
" system=system_message,\n",
|
||||
@@ -332,12 +332,12 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Claude 3.7 Sonnet again\n",
|
||||
"# Claude 4.0 Sonnet again\n",
|
||||
"# Now let's add in streaming back results\n",
|
||||
"# If the streaming looks strange, then please see the note below this cell!\n",
|
||||
"\n",
|
||||
"result = claude.messages.stream(\n",
|
||||
" model=\"claude-3-7-sonnet-latest\",\n",
|
||||
" model=\"claude-sonnet-4-20250514\",\n",
|
||||
" max_tokens=200,\n",
|
||||
" temperature=0.7,\n",
|
||||
" system=system_message,\n",
|
||||
@@ -408,12 +408,28 @@
|
||||
")\n",
|
||||
"\n",
|
||||
"response = gemini_via_openai_client.chat.completions.create(\n",
|
||||
" model=\"gemini-2.5-flash-preview-04-17\",\n",
|
||||
" model=\"gemini-2.5-flash\",\n",
|
||||
" messages=prompts\n",
|
||||
")\n",
|
||||
"print(response.choices[0].message.content)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "492f0ff2-8581-4836-bf00-37fddbe120eb",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Sidenote:\n",
|
||||
"\n",
|
||||
"This alternative approach of using the client library from OpenAI to connect with other models has become extremely popular in recent months.\n",
|
||||
"\n",
|
||||
"So much so, that all the models now support this approach - including Anthropic.\n",
|
||||
"\n",
|
||||
"You can read more about this approach, with 4 examples, in the first section of this guide:\n",
|
||||
"\n",
|
||||
"https://github.com/ed-donner/agents/blob/main/guides/09_ai_apis_and_ollama.ipynb"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "33f70c88-7ca9-470b-ad55-d93a57dcc0ab",
|
||||
@@ -583,7 +599,7 @@
|
||||
"# Have it stream back results in markdown\n",
|
||||
"\n",
|
||||
"stream = openai.chat.completions.create(\n",
|
||||
" model='gpt-4o-mini',\n",
|
||||
" model='gpt-4.1-mini',\n",
|
||||
" messages=prompts,\n",
|
||||
" temperature=0.7,\n",
|
||||
" stream=True\n",
|
||||
@@ -634,11 +650,11 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Let's make a conversation between GPT-4o-mini and Claude-3-haiku\n",
|
||||
"# Let's make a conversation between GPT-4.1-mini and Claude-3.5-haiku\n",
|
||||
"# We're using cheap versions of models so the costs will be minimal\n",
|
||||
"\n",
|
||||
"gpt_model = \"gpt-4o-mini\"\n",
|
||||
"claude_model = \"claude-3-haiku-20240307\"\n",
|
||||
"gpt_model = \"gpt-4.1-mini\"\n",
|
||||
"claude_model = \"claude-3-5-haiku-latest\"\n",
|
||||
"\n",
|
||||
"gpt_system = \"You are a chatbot who is very argumentative; \\\n",
|
||||
"you disagree with anything in the conversation and you challenge everything, in a snarky way.\"\n",
|
||||
@@ -774,6 +790,19 @@
|
||||
"\n",
|
||||
"Try creating a 3-way, perhaps bringing Gemini into the conversation! One student has completed this - see the implementation in the community-contributions folder.\n",
|
||||
"\n",
|
||||
"The most reliable way to do this involves thinking a bit differently about your prompts: just 1 system prompt and 1 user prompt each time, and in the user prompt list the full conversation so far.\n",
|
||||
"\n",
|
||||
"Something like:\n",
|
||||
"\n",
|
||||
"```python\n",
|
||||
"user_prompt = f\"\"\"\n",
|
||||
" You are Alex, in conversation with Blake and Charlie.\n",
|
||||
" The conversation so far is as follows:\n",
|
||||
" {conversation}\n",
|
||||
" Now with this, respond with what you would like to say next, as Alex.\n",
|
||||
" \"\"\"\n",
|
||||
"```\n",
|
||||
"\n",
|
||||
"Try doing this yourself before you look at the solutions. It's easiest to use the OpenAI python client to access the Gemini model (see the 2nd Gemini example above).\n",
|
||||
"\n",
|
||||
"## Additional exercise\n",
|
||||
@@ -824,7 +853,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.12"
|
||||
"version": "3.11.13"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
443
week2/day2.ipynb
443
week2/day2.ipynb
@@ -16,7 +16,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 1,
|
||||
"id": "c44c5494-950d-4d2f-8d4f-b87b57c5b330",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 2,
|
||||
"id": "d1715421-cead-400b-99af-986388a97aff",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -45,10 +45,20 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 3,
|
||||
"id": "337d5dfc-0181-4e3b-8ab9-e78e0c3f657b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"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",
|
||||
"Google API Key exists and begins AIzaSyA5\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Load environment variables in a file called .env\n",
|
||||
"# Print the key prefixes to help with any debugging\n",
|
||||
@@ -76,7 +86,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 4,
|
||||
"id": "22586021-1795-4929-8079-63f5bb4edd4c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -92,7 +102,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 5,
|
||||
"id": "b16e6021-6dc4-4397-985a-6679d6c8ffd5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -104,7 +114,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 6,
|
||||
"id": "02ef9b69-ef31-427d-86d0-b8c799e1c1b1",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -125,10 +135,21 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 7,
|
||||
"id": "aef7d314-2b13-436b-b02d-8de3b72b193f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"\"Today's date is October 10, 2023.\""
|
||||
]
|
||||
},
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# This can reveal the \"training cut off\", or the most recent date in the training data\n",
|
||||
"\n",
|
||||
@@ -145,7 +166,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 8,
|
||||
"id": "bc664b7a-c01d-4fea-a1de-ae22cdd5141a",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -159,20 +180,67 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 9,
|
||||
"id": "083ea451-d3a0-4d13-b599-93ed49b975e4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Shout has been called with input hello\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'HELLO'"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"shout(\"hello\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 10,
|
||||
"id": "08f1f15a-122e-4502-b112-6ee2817dda32",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7860\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": 10,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# The simplicty of gradio. This might appear in \"light mode\" - I'll show you how to make this in dark mode later.\n",
|
||||
"\n",
|
||||
@@ -181,10 +249,41 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 11,
|
||||
"id": "c9a359a4-685c-4c99-891c-bb4d1cb7f426",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7861\n",
|
||||
"* Running on public URL: https://c1f6ab5bdc2722c539.gradio.live\n",
|
||||
"\n",
|
||||
"This share link expires in 1 week. For free permanent hosting and GPU upgrades, run `gradio deploy` from the terminal in the working directory to deploy to Hugging Face Spaces (https://huggingface.co/spaces)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"https://c1f6ab5bdc2722c539.gradio.live\" 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": 11,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Adding share=True means that it can be accessed publically\n",
|
||||
"# A more permanent hosting is available using a platform called Spaces from HuggingFace, which we will touch on next week\n",
|
||||
@@ -195,10 +294,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 12,
|
||||
"id": "cd87533a-ff3a-4188-8998-5bedd5ba2da3",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7862\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7862/\" 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": 12,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Adding inbrowser=True opens up a new browser window automatically\n",
|
||||
"\n",
|
||||
@@ -217,10 +345,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 13,
|
||||
"id": "e8129afa-532b-4b15-b93c-aa9cca23a546",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7863\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7863/\" 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": 13,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Define this variable and then pass js=force_dark_mode when creating the Interface\n",
|
||||
"\n",
|
||||
@@ -238,10 +395,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 15,
|
||||
"id": "3cc67b26-dd5f-406d-88f6-2306ee2950c0",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7865\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7865/\" 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": 15,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Inputs and Outputs\n",
|
||||
"\n",
|
||||
@@ -256,10 +442,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 16,
|
||||
"id": "f235288e-63a2-4341-935b-1441f9be969b",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7866\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7866/\" 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": 16,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# And now - changing the function from \"shout\" to \"message_gpt\"\n",
|
||||
"\n",
|
||||
@@ -274,10 +489,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 17,
|
||||
"id": "af9a3262-e626-4e4b-80b0-aca152405e63",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7867\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7867/\" 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": 17,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"# Let's use Markdown\n",
|
||||
"# Are you wondering why it makes any difference to set system_message when it's not referred to in the code below it?\n",
|
||||
@@ -297,7 +541,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 18,
|
||||
"id": "88c04ebf-0671-4fea-95c9-bc1565d4bb4f",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -324,10 +568,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 19,
|
||||
"id": "0bb1f789-ff11-4cba-ac67-11b815e29d09",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7868\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7868/\" 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": 19,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"view = gr.Interface(\n",
|
||||
" fn=stream_gpt,\n",
|
||||
@@ -340,7 +613,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 20,
|
||||
"id": "bbc8e930-ba2a-4194-8f7c-044659150626",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -364,10 +637,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 21,
|
||||
"id": "a0066ffd-196e-4eaf-ad1e-d492958b62af",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7869\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7869/\" 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": 21,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"view = gr.Interface(\n",
|
||||
" fn=stream_claude,\n",
|
||||
@@ -403,7 +705,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 22,
|
||||
"id": "0087623a-4e31-470b-b2e6-d8d16fc7bcf5",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -420,10 +722,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 23,
|
||||
"id": "8d8ce810-997c-4b6a-bc4f-1fc847ac8855",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7870\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7870/\" 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": 23,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"view = gr.Interface(\n",
|
||||
" fn=stream_model,\n",
|
||||
@@ -466,7 +797,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 24,
|
||||
"id": "1626eb2e-eee8-4183-bda5-1591b58ae3cf",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -494,7 +825,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 25,
|
||||
"id": "c701ec17-ecd5-4000-9f68-34634c8ed49d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
@@ -507,12 +838,13 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 28,
|
||||
"id": "5def90e0-4343-4f58-9d4a-0e36e445efa4",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def stream_brochure(company_name, url, model):\n",
|
||||
" yield \"\"\n",
|
||||
" prompt = f\"Please generate a company brochure for {company_name}. Here is their landing page:\\n\"\n",
|
||||
" prompt += Website(url).get_contents()\n",
|
||||
" if model==\"GPT\":\n",
|
||||
@@ -526,10 +858,39 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"execution_count": 30,
|
||||
"id": "66399365-5d67-4984-9d47-93ed26c0bd3d",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"* Running on local URL: http://127.0.0.1:7873\n",
|
||||
"* To create a public link, set `share=True` in `launch()`.\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div><iframe src=\"http://127.0.0.1:7873/\" 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": 30,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"view = gr.Interface(\n",
|
||||
" fn=stream_brochure,\n",
|
||||
@@ -568,7 +929,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.12"
|
||||
"version": "3.11.13"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -301,7 +301,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.11"
|
||||
"version": "3.11.13"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
Reference in New Issue
Block a user