{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "17d6b46e-8c81-49b6-b478-48826c091fc3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from dotenv import load_dotenv, find_dotenv\n",
    "_ = load_dotenv(find_dotenv())\n",
    "openai_api_key = os.environ[\"OPENAI_API_KEY\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d41f440-273f-4efd-86a5-b0ac05164db4",
   "metadata": {},
   "source": [
    "## GPT-4 128k Context Length\n",
    "* Changes RAG: Now you can load one book at a time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4243f9ff-47e0-497e-89bc-eaaa5c5840bc",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "\n",
    "with open(\"my_long_document.txt\") as f:\n",
    "    book_text = f.read()\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    model=\"gpt-4-1106-preview\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": book_text + \"My question about the document?\"\n",
    "        }\n",
    "    ]\n",
    ")\n",
    "\n",
    "print(response.choices[0].message.content)\n",
    "\n",
    "print(f\"\\nTotal tokens: {response.usage.total_tokens}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e68a57f-7a74-4806-b5c7-469da070a4f6",
   "metadata": {},
   "source": [
    "## Multiple Function Calling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ed961a2-48ec-4ee7-a03e-9e965d595cb3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "\n",
    "messages = [\n",
    "    {\n",
    "        \"role\": \"user\",\n",
    "        \"content\": input(\"Message: \")\n",
    "    }\n",
    "]\n",
    "\n",
    "tools = [\n",
    "    {\n",
    "        \"type\": \"function\",\n",
    "        \"function\": {\n",
    "            \"name\": \"play_song\",\n",
    "            \"description\": \"Play a song\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"song_name\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"The name of the song to play\",\n",
    "                    },\n",
    "                },\n",
    "                \"required\": [\"song_name\"],\n",
    "            },\n",
    "        },\n",
    "    },\n",
    "    {\n",
    "        \"type\": \"function\",\n",
    "        \"function\": {\n",
    "            \"name\": \"light_dimmer\",\n",
    "            \"description\": \"Adjust the light dimmer from 0-100\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"brightness\": {\n",
    "                        \"type\": \"number\",\n",
    "                        \"description\": \"The brightness from 0-100\",\n",
    "                    },\n",
    "                },\n",
    "                \"required\": [\"brightness\"],\n",
    "            },\n",
    "        },\n",
    "    },\n",
    "    {\n",
    "        \"type\": \"function\",\n",
    "        \"function\": {\n",
    "            \"name\": \"order_food\",\n",
    "            \"description\": \"Order food from a restaurant\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"dish_name\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"The name of the dish to order\",\n",
    "                    },\n",
    "                    \"count\": {\n",
    "                        \"type\": \"number\",\n",
    "                        \"description\": \"The number of dishes to order\",\n",
    "                    },\n",
    "                },\n",
    "                \"required\": [\"dish_name\", \"count\"],\n",
    "            },\n",
    "        },\n",
    "    },\n",
    "    {\n",
    "        \"type\": \"function\",\n",
    "        \"function\": {\n",
    "            \"name\": \"send_sms\",\n",
    "            \"description\": \"Send a text message to a contact\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"contact_name\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"The name of the contact\",\n",
    "                    },\n",
    "                    \"message\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"The text message content\",\n",
    "                    },\n",
    "                },\n",
    "                \"required\": [\"contact_name\", \"message\"],\n",
    "            },\n",
    "        },\n",
    "    }\n",
    "]\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    #model=\"gpt-3.5-turbo-1106\",\n",
    "    model=\"gpt-4-1106-preview\",\n",
    "    messages=messages,\n",
    "    tools=tools,\n",
    "    tool_choice=\"auto\",\n",
    ")\n",
    "\n",
    "response_message = response.choices[0].message\n",
    "\n",
    "tool_calls = response_message.tool_calls\n",
    "\n",
    "messages.append(response_message)\n",
    "\n",
    "for tool_call in tool_calls:\n",
    "    function_name = tool_call.function.name\n",
    "    arguments = tool_call.function.arguments\n",
    "    print(f\"Called '{function_name}' with args {arguments}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66761ae6-a4ae-4f2c-b35b-dd083bfcc821",
   "metadata": {},
   "source": [
    "## JSON Mode\n",
    "* Changes: the most popular Output Parser is not needed anymore."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a91df214-5bb7-467e-aaef-12dd62851271",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "import json\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    model=\"gpt-3.5-turbo-1106\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"system\",\n",
    "            \"content\": \"You are a book suggester. Respond with a book title, description and category in JSON format.\"\n",
    "        },\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"I want to make lots of money\"\n",
    "        }\n",
    "    ],\n",
    "    response_format={\"type\": \"json_object\"}\n",
    ")\n",
    "\n",
    "print(\n",
    "    json.dumps(\n",
    "        json.loads(\n",
    "            response.choices[0].message.content\n",
    "        ),\n",
    "        indent=4\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45e0ec55-0796-4a6d-a5de-38dd4fa18c76",
   "metadata": {},
   "source": [
    "## Reproducible Outputs (Seed Parameter)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c9b444d-a9c7-4de3-b326-63efbbf6dd55",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    model=\"gpt-3.5-turbo-1106\",\n",
    "    seed=3453,\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"Create a story about a boy and his dog. Give them names\"\n",
    "        }\n",
    "    ],\n",
    "    max_tokens=256,\n",
    ")\n",
    "\n",
    "print(response.choices[0].message.content)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9278714a-98cc-4473-8a39-22c2eedde46a",
   "metadata": {},
   "source": [
    "## Assistants"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5c87af25-c47d-4f65-a5ac-67c03785b94b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "\n",
    "assistant = openai.beta.assistants.create(\n",
    "    model=\"gpt-3.5-turbo-1106\",\n",
    "    name=\"Riddlebot\",\n",
    "    instructions=\"You answer all questions in riddles\",\n",
    ")\n",
    "\n",
    "print(f\"Assistant ID: {assistant.id}\")\n",
    "\n",
    "thread = openai.beta.threads.create(\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"How do I get started with Python?\",\n",
    "        }\n",
    "    ]\n",
    ")\n",
    "\n",
    "print(f\"Thread ID: {thread.id}\")\n",
    "\n",
    "run = openai.beta.threads.runs.create(\n",
    "    thread_id=thread.id,\n",
    "    assistant_id=assistant.id,\n",
    ")\n",
    "\n",
    "print(f\"Run ID: {run.id}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb34ee52-46f1-49b8-a1b4-d6282e80cd88",
   "metadata": {},
   "source": [
    "## RAG Assistant\n",
    "* Changes RAG: not necessary for simple cases.\n",
    "* RAG still necessary for complex and sophisticated cases."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7d9b9f1f-8cd3-415a-a0ed-5ae1945e0729",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "\n",
    "file = openai.files.create(\n",
    "    file=openai.file_from_path(\"file.pdf\"),\n",
    "    purpose=\"assistants\",\n",
    ")\n",
    "\n",
    "assistant = openai.beta.assistants.create(\n",
    "    model=\"gpt-3.5-turbo-1106\",\n",
    "    file_ids=[\n",
    "        file.id,\n",
    "    ],\n",
    "    tools=[\n",
    "        {\"type\": \"retrieval\"},\n",
    "    ]\n",
    ")\n",
    "\n",
    "thread = openai.beta.threads.create()\n",
    "\n",
    "print(f\"File ID: {file.id}\")\n",
    "print(f\"Assistant ID: {assistant.id}\")\n",
    "print(f\"Thread ID: {thread.id}\\n\")\n",
    "\n",
    "print(\"GPT: Hello! How can I assist you today?\")\n",
    "\n",
    "while True:\n",
    "    message = input(\"You: \")\n",
    "    print()\n",
    "\n",
    "    openai.beta.threads.messages.create(\n",
    "        thread_id=thread.id,\n",
    "        role=\"user\",\n",
    "        content=message,\n",
    "    )\n",
    "\n",
    "    run = openai.beta.threads.runs.create(\n",
    "        thread_id=thread.id,\n",
    "        assistant_id=assistant.id,\n",
    "    )\n",
    "\n",
    "    while True:\n",
    "        run = openai.beta.threads.runs.retrieve(\n",
    "            run_id=run.id,\n",
    "            thread_id=thread.id,\n",
    "        )\n",
    "\n",
    "        if run.status not in [\"queued\", \"in_progress\", \"cancelling\"]:\n",
    "            break\n",
    "\n",
    "    messages = openai.beta.threads.messages.list(\n",
    "        thread_id=thread.id,\n",
    "        limit=1,\n",
    "    )\n",
    "    print(\"GPT: \" + messages.data[0].content[0].text.value)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "572a0506-0eae-46d8-a2a8-4ea093da8359",
   "metadata": {},
   "source": [
    "## Multi-modality: Vision"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "242d2c68-2fa0-4a38-948d-6e985fe7e940",
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "import base64\n",
    "\n",
    "def encode_image(image_path):\n",
    "    with open(image_path, \"rb\") as f:\n",
    "        return base64.b64encode(f.read()).decode()\n",
    "\n",
    "base64_image = encode_image(\"test.jpg\")\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    model=\"gpt-4-vision-preview\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": [\n",
    "                {\n",
    "                    \"type\": \"text\",\n",
    "                    \"text\": \"What's in this image?\",\n",
    "                },\n",
    "                {\n",
    "                    \"type\": \"image_url\",\n",
    "                    \"image_url\": f\"data:image/jpeg;base64,{base64_image}\",\n",
    "                }\n",
    "            ]\n",
    "        }\n",
    "    ]\n",
    ")\n",
    "\n",
    "print(response.choices[0].message.content)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c2ca626-13d4-45f3-8189-1172ea814fa0",
   "metadata": {},
   "source": [
    "## Multi-modality: Audio (TextSpeech)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69ba8815-e5b5-4987-968f-76dd4945da6f",
   "metadata": {},
   "outputs": [],
   "source": [
    "import playsound\n",
    "import openai\n",
    "import json\n",
    "import os\n",
    "\n",
    "def play_with_voice(voice, speech):\n",
    "    audio = openai.audio.speech.create(\n",
    "        input=speech,\n",
    "        model=\"tts-1\",\n",
    "        voice=voice,\n",
    "    )\n",
    "\n",
    "    audio.stream_to_file(\"audio.mp3\")\n",
    "    playsound.playsound(\"audio.mp3\")\n",
    "    os.remove(\"audio.mp3\")\n",
    "\n",
    "def mark_speaks(speech):\n",
    "    play_with_voice(\"echo\", speech)\n",
    "\n",
    "def lisa_speaks(speech):\n",
    "    play_with_voice(\"nova\", speech)\n",
    "\n",
    "response = openai.chat.completions.create(\n",
    "    model=\"gpt-3.5-turbo-1106\",\n",
    "    messages=[\n",
    "        {\n",
    "            \"role\": \"system\",\n",
    "            \"content\": \"You are a conversation generator. Generate the full conversation using function calls. Call the speech functions 5 times for both Mark and Lisa\",\n",
    "        },\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"Create a conversation between Lisa and Mark. They're talking about Rust vs C++\"\n",
    "        }\n",
    "    ],\n",
    "    tools=[\n",
    "        {\n",
    "            \"type\": \"function\",\n",
    "            \"function\": {\n",
    "                \"name\": \"mark_speaks\",\n",
    "                \"parameters\": {\n",
    "                    \"type\": \"object\",\n",
    "                    \"properties\": {\n",
    "                        \"speech\": {\n",
    "                            \"type\": \"string\"\n",
    "                        }\n",
    "                    }\n",
    "                }\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            \"type\": \"function\",\n",
    "            \"function\": {\n",
    "                \"name\": \"lisa_speaks\",\n",
    "                \"parameters\": {\n",
    "                    \"type\": \"object\",\n",
    "                    \"properties\": {\n",
    "                        \"speech\": {\n",
    "                            \"type\": \"string\"\n",
    "                        }\n",
    "                    }\n",
    "                }\n",
    "            }\n",
    "        }\n",
    "    ]\n",
    ")\n",
    "\n",
    "for tool_call in response.choices[0].message.tool_calls:\n",
    "    function_name = tool_call.function.name\n",
    "    arguments = json.loads(tool_call.function.arguments)\n",
    "\n",
    "    print(function_name + \": \" + arguments[\"speech\"])\n",
    "\n",
    "    if function_name in [\"mark_speaks\", \"lisa_speaks\"]:\n",
    "        globals()[function_name](**arguments)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "610bdbaf-2d42-4faa-b5e3-acdbe7167c9a",
   "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.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
