diff --git a/part1-fundementals/community-contributions/ninad-bodas/lab1_challenge.ipynb b/part1-fundementals/community-contributions/ninad-bodas/lab1_challenge.ipynb new file mode 100644 index 0000000..dec44cf --- /dev/null +++ b/part1-fundementals/community-contributions/ninad-bodas/lab1_challenge.ipynb @@ -0,0 +1,485 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "73429c45", + "metadata": {}, + "source": [ + "### Import libraries and API Keys" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "52a58afd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import os\n", + "from openai import OpenAI\n", + "from dotenv import load_dotenv\n", + "from IPython.display import display, Markdown\n", + "load_dotenv()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "229d65dc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "OpenAI API key is set\n", + "Gemini API key is set\n", + "Perplexity API key is set\n" + ] + } + ], + "source": [ + "\n", + "OPENAI_API_KEY = os.getenv(\"OPENAI_API_KEY\")\n", + "GEMINI_API_KEY = os.getenv(\"GEMINI_API_KEY\")\n", + "PERPLEXITY_API_KEY = os.getenv(\"PERPLEXITY_API_KEY\")\n", + "\n", + "# check if API keys are set\n", + "if not OPENAI_API_KEY:\n", + " raise ValueError(\"Missing OpenAI API key\")\n", + "if not GEMINI_API_KEY:\n", + " raise ValueError(\"Missing Gemini API key\")\n", + "if not PERPLEXITY_API_KEY:\n", + " raise ValueError(\"Missing Perplexity API key\")\n", + "if OPENAI_API_KEY:\n", + " print(\"OpenAI API key is set\")\n", + "if GEMINI_API_KEY:\n", + " print(\"Gemini API key is set\")\n", + "if PERPLEXITY_API_KEY:\n", + " print(\"Perplexity API key is set\")" + ] + }, + { + "cell_type": "markdown", + "id": "77ec2cc7", + "metadata": {}, + "source": [ + "### Intiate Open AI Client" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "699f22a8", + "metadata": {}, + "outputs": [], + "source": [ + "# client\n", + "openai_client = OpenAI(api_key=PERPLEXITY_API_KEY, base_url=\"https://api.perplexity.ai\")" + ] + }, + { + "cell_type": "markdown", + "id": "2f15e0dc", + "metadata": {}, + "source": [ + "### Create message list for Open AI Client" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "69a5864f", + "metadata": {}, + "outputs": [], + "source": [ + "# message list\n", + "message = \"I want to generate support ticket for the customer who is facing issue with login to the application. \"\n", + "message+= \"The customer is using iOS app on iPhone 17 running iOS 26.0. \"\n", + "message+= \"The error message displayed is 'Invalid credentials'. \"\n", + "message+= \"Include device details and reate ticekt title\"\n", + "message+= \"Do not include any personal information about the customer. \"\n", + "message+= \"Do not include detailed description of the issue. And do not include any trobleshooting steps.\"\n", + "message+= \"Generate the ticket with title and description only.\"" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "d14cfeea", + "metadata": {}, + "outputs": [], + "source": [ + "messages = [{\"role\": \"user\", \"content\": message}]" + ] + }, + { + "cell_type": "markdown", + "id": "1eaa58be", + "metadata": {}, + "source": [ + "### Generate Ticket" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "eb19ad76", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "### Generated Ticket:\n", + "### Ticket Title\n", + "**iOS App Login Issue: Invalid Credentials on iPhone 17 (iOS 26.0)**\n", + "\n", + "### Description\n", + "Customer reports 'Invalid credentials' error during login attempt. Device: iPhone 17 running iOS 26.0 via iOS app.[2][3]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "#Generate ticket\n", + "\n", + "openai_response = openai_client.chat.completions.create(\n", + " model=\"sonar\",\n", + " messages=messages\n", + ")\n", + "\n", + "ticket = openai_response.choices[0].message.content\n", + "display(Markdown(f\"### Generated Ticket:\\n{ticket}\"))" + ] + }, + { + "cell_type": "markdown", + "id": "60693028", + "metadata": {}, + "source": [ + "### Set Priority of the ticket" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "132b7e80", + "metadata": {}, + "outputs": [], + "source": [ + "message = \"Classify the priority of the following customer support ticket \"\n", + "message += \"The ticket is as follows: \"+ ticket + \" \"\n", + "message += \"Please classify the priority as either 'Low', 'Medium', or 'High'. \"\n", + "message += \"Respond with ticket title, ticket description and ticket priority level only.\"\n", + "\n", + "messages = [{\"role\": \"user\", \"content\": message}]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "9e77cdb3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "### Ticket Priority:\n", + "### Ticket Title\n", + "**iOS App Login Issue: Invalid Credentials on iPhone 17 (iOS 26.0)**\n", + "\n", + "### Description\n", + "Customer reports 'Invalid credentials' error during login attempt. Device: iPhone 17 running iOS 26.0 via iOS app.[2][3]\n", + "\n", + "### Ticket Priority Level\n", + "**Medium**[1][2][4]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "openai_response = openai_client.chat.completions.create(\n", + " model=\"sonar\",\n", + " messages=messages\n", + ")\n", + "\n", + "priority = openai_response.choices[0].message.content \n", + "#display(Markdown(f\"### Generated Ticket:\\n{ticket}\"))\n", + "display(Markdown(f\"### Ticket Priority:\\n{priority}\"))" + ] + }, + { + "cell_type": "markdown", + "id": "9450b156", + "metadata": {}, + "source": [ + "### Create 1st Response" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "467ff340", + "metadata": {}, + "outputs": [], + "source": [ + "# message list\n", + "\n", + "message = \"Create response email for the following customer support ticket.\"\n", + "message += \"The ticket is as follows: \"+ ticket + \" \"\n", + "message += \"The email should be professional and customer friendly.\"\n", + "message += \"Include only Subject and Body in the email.\"\n", + "message += \"Do not include any greetings or sign-offs.\"\n", + "message += \"Body should be concise and to the point.\"\n", + "\n", + "messages = [{\"role\": \"user\", \"content\": message}]" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "6f0514a4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "### Email Response:\n", + "**Subject:** Help with iOS App Login Issue on iPhone 17 (iOS 26.0)\n", + "\n", + "Thank you for reporting the \"Invalid credentials\" error during login on your iPhone 17 running iOS 26.0.[2][3]\n", + "\n", + "To resolve this, please try these steps in order:\n", + "\n", + "- Manually type your username and password instead of using autofill.[1]\n", + "- Update the app to the latest version via the App Store.[2]\n", + "- Go to **Settings > General > VPN & Device Management**, turn off any VPN profiles, then attempt login; if needed, delete and reinstall them later.[2]\n", + "- Reset your password if it may have changed or if issues persist.[1][2]\n", + "- Restart your device by quickly pressing volume up, then volume down, then holding the side button.[2]\n", + "\n", + "If these do not work, reply with more details (e.g., does login succeed in a web browser?). We'll assist further.[5]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "openai_response = openai_client.chat.completions.create(\n", + " model=\"sonar\",\n", + " messages=messages\n", + ")\n", + "\n", + "response = openai_response.choices[0].message.content \n", + "display(Markdown(f\"### Email Response:\\n{response}\"))" + ] + }, + { + "cell_type": "markdown", + "id": "3afacb97", + "metadata": {}, + "source": [ + "### Pass to Evaluator & Optimizer" + ] + }, + { + "cell_type": "markdown", + "id": "40238c6a", + "metadata": {}, + "source": [ + "We will use Gemini as Evaluator and Optimizer" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "93aba2ac", + "metadata": {}, + "outputs": [], + "source": [ + "gemini_client = OpenAI(api_key=GEMINI_API_KEY, base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\")" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "19ac5816", + "metadata": {}, + "outputs": [], + "source": [ + "# message list\n", + "\n", + "message = \"Take the input generated response email.\"\n", + "message += \"The email is as follows: \" + response + \" \"\n", + "message += \"Evaluate the email for professionalism and customer friendliness.\"\n", + "message += \"Analyze the response and suggest what can be improved in the email.\"\n", + "message += \"Print the list of improvements only\"\n", + "message += \"Do not print the original email or any other text.\"\n", + "messages = [{\"role\": \"user\", \"content\": message}]" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "3b4b51d0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "### List of Improvements:\n", + "Here is a list of improvements for the email:\n", + "\n", + "* **Remove internal reference numbers:** The `[1][2][6]` and similar notations within the email text are internal references and appear unprofessional and confusing to the customer. They should be removed.\n", + "* **Add a professional closing and signature:** The email ends abruptly. Include a professional closing such as \"Sincerely,\" \"Best regards,\" or \"Kind regards,\" followed by the support team's name or company name.\n", + "* **Enhance empathy and warmth in the body:** While the opening is good, the instructions are quite direct. Adding phrases like \"We appreciate your patience as you try these steps\" or \"We're committed to helping you get this resolved\" can make the tone more customer-friendly.\n", + "* **Provide brief explanations for less common troubleshooting steps:** For steps like \"Set date and time to automatic\" or \"Turn off or remove VPN,\" briefly explaining *why* these steps might help (e.g., \"to ensure proper synchronization with our servers\" or \"VPNs can sometimes interfere with secure connections\") can make the instructions clearer and more reassuring.\n", + "* **Offer more detailed next steps for persistent issues:** While \"reply to this email\" is clear, you could add what to expect next (e.g., \"If issues persist, please reply to this email, and we'll be happy to investigate further, perhaps requesting screenshots or more details about your setup.\")." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "gemini_response = gemini_client.chat.completions.create(\n", + " model=\"gemini-2.5-flash\",\n", + " messages=messages\n", + ")\n", + "\n", + "improv_list = gemini_response.choices[0].message.content \n", + "display(Markdown(f\"### List of Improvements:\\n{improv_list}\"))" + ] + }, + { + "cell_type": "markdown", + "id": "ee9a175f", + "metadata": {}, + "source": [ + "### Pass back to response client to improve the response" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "49698e60", + "metadata": {}, + "outputs": [], + "source": [ + "# message list\n", + "\n", + "message = \"Update the response email incorporating the improvements.\"\n", + "message += \"Improvements suggested by optimizer-evaluator: \" + improv_list + \" \"\n", + "message += \"The ticket is as follows: \"+ ticket + \" \"\n", + "message += \"The email should be professional and customer friendly.\"\n", + "message += \"Include only Subject and Body in the email.\"\n", + "message += \"Do not include any greetings or sign-offs.\"\n", + "message += \"Body should be concise and to the point.\"\n", + "\n", + "messages = [{\"role\": \"user\", \"content\": message}]" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "d22eea46", + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "### Email Response:\n", + "**Subject:** Steps to Resolve Your iOS App Login Issue on iPhone 17 (iOS 26.0)\n", + "\n", + "Thank you for reaching out about the \"Invalid credentials\" error you're encountering when logging into our iOS app on your iPhone 17 running iOS 26.0. We're committed to helping you get this resolved quickly and appreciate your patience as you try these troubleshooting steps.\n", + "\n", + "Here are some common fixes that often resolve this issue:\n", + "\n", + "- **Update the app:** Ensure you're running the latest version from the App Store, as updates frequently address login bugs.\n", + "- **Restart your device:** A simple reboot can clear temporary glitches affecting authentication.\n", + "- **Set date and time to automatic:** Go to Settings > General > Date & Time and enable \"Set Automatically.\" This ensures proper synchronization with our servers for secure login.\n", + "- **Turn off or remove VPN:** VPNs can sometimes interfere with secure connections. Disable any VPN apps temporarily and try logging in again.\n", + "- **Clear app cache or reinstall:** In the app settings, clear cache if available, or delete and reinstall the app to refresh your login data.\n", + "\n", + "If these steps don't resolve the issue, please reply to this email with more details about your setup—such as screenshots of the error or any VPN/network info—and we'll investigate further right away.\n", + "\n", + "Best regards, \n", + "Support Team \n", + "[Your Company Name]" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "openai_response = openai_client.chat.completions.create(\n", + " model=\"sonar\",\n", + " messages=messages\n", + ")\n", + "\n", + "response = openai_response.choices[0].message.content \n", + "display(Markdown(f\"### Email Response:\\n{response}\"))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9ed5d872", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "agentic-ai", + "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.13.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/part1-fundementals/lab1.ipynb b/part1-fundementals/lab1.ipynb index d113760..b4b4c30 100644 --- a/part1-fundementals/lab1.ipynb +++ b/part1-fundementals/lab1.ipynb @@ -26,19 +26,17 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "8f696afb", "metadata": {}, "outputs": [ { - "ename": "ValueError", - "evalue": "Missing Gemini API key", - "output_type": "error", - "traceback": [ - "\u001b[31m---------------------------------------------------------------------------\u001b[39m", - "\u001b[31mValueError\u001b[39m Traceback (most recent call last)", - "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 17\u001b[39m\n\u001b[32m 15\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mMissing OpenAI API key\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 16\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m GEMINI_API_KEY:\n\u001b[32m---> \u001b[39m\u001b[32m17\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mMissing Gemini API key\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m 18\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m ANTHROPIC_API_KEY:\n\u001b[32m 19\u001b[39m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[33m\"\u001b[39m\u001b[33mMissing Anthropic API key\u001b[39m\u001b[33m\"\u001b[39m)\n", - "\u001b[31mValueError\u001b[39m: Missing Gemini API key" + "name": "stdout", + "output_type": "stream", + "text": [ + "OpenAI API key is set\n", + "Gemini API key is set\n", + "Anthropic API key is set\n" ] } ], @@ -61,7 +59,13 @@ "if not GEMINI_API_KEY:\n", " raise ValueError(\"Missing Gemini API key\")\n", "if not ANTHROPIC_API_KEY:\n", - " raise ValueError(\"Missing Anthropic API key\")" + " raise ValueError(\"Missing Anthropic API key\")\n", + "if OPENAI_API_KEY:\n", + " print(\"OpenAI API key is set\")\n", + "if GEMINI_API_KEY:\n", + " print(\"Gemini API key is set\")\n", + "if ANTHROPIC_API_KEY:\n", + " print(\"Anthropic API key is set\")" ] }, { @@ -107,10 +111,9 @@ "id": "01562382", "metadata": {}, "source": [ - "```mermaid\n", + "mermaid\n", "graph LR\n", - " A[Generate Tickets] --> B[Classify Priority] --> C[Respond to Tickets]\n", - "```" + " A[Generate Tickets] --> B[Classify Priority] --> C[Respond to Tickets]\n" ] }, { @@ -123,18 +126,20 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 12, "id": "24530e43", "metadata": {}, "outputs": [], "source": [ "# client\n", - "openai_client = OpenAI()" + "#openai_client = OpenAI()\n", + "#openai_client = OpenAI(api_key=ANTHROPIC_API_KEY, base_url=\"https://api.anthropic.com/v1\")\n", + "openai_client = OpenAI(api_key=GEMINI_API_KEY, base_url=\"https://generativelanguage.googleapis.com/v1beta/openai/\")" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 13, "id": "11ab44e3", "metadata": {}, "outputs": [], @@ -150,7 +155,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 14, "id": "2aa74d83", "metadata": {}, "outputs": [ @@ -158,7 +163,7 @@ "data": { "text/markdown": [ "### Generated Ticket:\n", - "The product I received is not functioning as advertised and there are several missing components." + "The tracking information for my recent order hasn't updated in three days, and the estimated delivery date has already passed." ], "text/plain": [ "" @@ -171,9 +176,14 @@ "source": [ "# response\n", "\n", - "openai_response = openai_client.chat.completions.create(\n", + "'''openai_response = openai_client.chat.completions.create(\n", " model=\"gpt-4.1-nano\",\n", " messages=messages\n", + ")'''\n", + "\n", + "openai_response = openai_client.chat.completions.create(\n", + " model=\"gemini-2.5-flash\",\n", + " messages=messages\n", ")\n", "\n", "ticket = openai_response.choices[0].message.content\n", @@ -203,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "id": "42d3443c", "metadata": {}, "outputs": [], @@ -214,7 +224,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "id": "4affb2ef", "metadata": {}, "outputs": [], @@ -230,24 +240,10 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": null, "id": "0e7c7c08", "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "### Classified Priority:\n", - "High" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# response\n", "\n", @@ -270,7 +266,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "id": "5c2304b7", "metadata": {}, "outputs": [], @@ -281,7 +277,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": null, "id": "9b123501", "metadata": {}, "outputs": [], @@ -298,33 +294,10 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": null, "id": "3addbecc", "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "### Generated Response:\n", - "Subject: Re: Damaged Product - Urgent Replacement\n", - "\n", - "Dear [Customer Name, if available, otherwise 'Valued Customer'],\n", - "\n", - "I'm truly sorry to hear your product arrived damaged and isn't functioning.\n", - "\n", - "We'll arrange an immediate replacement for you. Please reply with your order number so we can process your new shipment right away.\n", - "\n", - "Sincerely,\n", - "[Your Name/Support Team]" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "# response\n", "\n", @@ -380,7 +353,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.9" + "version": "3.13.11" } }, "nbformat": 4,