{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ddfa9ae6-69fe-444a-b994-8c4c5970a7ec",
   "metadata": {},
   "source": [
    "# ๐Ÿ› ๏ธ Project โ€“ Art-Tech Store AI Assistant\n",
    "\n",
    "## ๐Ÿ›๏ธ Product Availability\n",
    "- Check availability of **printers** and **printer papers** with:\n",
    "  - Product name, price, brand, type (e.g., laser/inkjet), and stock status.\n",
    "- Alerts user if a product is out of stock.\n",
    "\n",
    "## ๐Ÿงญ Guided Shopping Experience\n",
    "- Guides users through:\n",
    "  1. Choosing product category (printer or paper)\n",
    "  2. Filtering options (brand, price range, type)\n",
    "  3. Adding selected products to cart\n",
    "- Ensures correct input for smooth shopping flow.\n",
    "\n",
    "## ๐Ÿงพ Receipt Generation\n",
    "- Creates a unique receipt file: `customerName_orderNumber.txt`\n",
    "- Receipt includes:\n",
    "  - Customer name and contact\n",
    "  - Product details (name, price, quantity)\n",
    "  - Total cost and order summary\n",
    "\n",
    "## ๐Ÿ“ฆ Generate Order Summary Report\n",
    "- Summarizes all purchases into a single file: `order_summary.txt`\n",
    "- Useful for inventory and sales review\n",
    "\n",
    "## ๐ŸŽฏ Product Recommendation\n",
    "- Recommends:\n",
    "  - Printers based on paper type, usage (home/office), or brand preference\n",
    "  - Compatible paper based on selected printer\n",
    "\n",
    "## ๐Ÿ’ฌ Interactive Chat Interface\n",
    "- Real-time conversation via **Gradio**\n",
    "- Polite, helpful answers to product-related questions\n",
    "\n",
    "## ๐Ÿ› ๏ธ Modular Tool Support\n",
    "- Integrated tools for:\n",
    "  - Checking product availability\n",
    "  - Adding to cart and generating receipts\n",
    "  - Creating summary reports\n",
    "- Easily extendable for:\n",
    "  - Promotions\n",
    "  - Customer reviews\n",
    "  - Delivery tracking\n",
    "\n",
    "## ๐Ÿ›ก๏ธ Error Handling\n",
    "- Validates user inputs (e.g., product name, quantity)\n",
    "- Graceful messages to guide user and prevent mistakes\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "747e8786-9da8-4342-b6c9-f5f69c2e22ae",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import json\n",
    "import random\n",
    "from dotenv import load_dotenv\n",
    "import gradio as gr\n",
    "from openai import OpenAI\n",
    "\n",
    "load_dotenv()\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",
    "MODEL = \"gpt-3.5-turbo\"\n",
    "openai = OpenAI()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6072536-eee1-4f87-9f03-8dc88dc04f1a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Using local LLM (that can't even handle basic greeting like Hi!!\n",
    "\n",
    "# MODEL = \"llama3.2\"\n",
    "# openai = OpenAI(base_url='http://localhost:11434/v1', api_key='ollama')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5fe5f5d7-0bd1-41a2-a654-59b587882f22",
   "metadata": {},
   "outputs": [],
   "source": [
    "###############################################################################\n",
    "# 1) System Prompt\n",
    "###############################################################################\n",
    "system_message = (\n",
    "    \"You are a helpful assistant for an online store called art-tech.store that sells printers and printer papers.\\n\\n\"\n",
    "    \"When the user wants to purchase a product, follow these steps:\\n\"\n",
    "    \"1. Ask whether they are interested in printers or printer papers.\\n\"\n",
    "    \"2. Ask for filtering preferences (e.g., brand, price range, type).\\n\"\n",
    "    \"3. Call the function 'check_product_availability' with the selected category and filters.\\n\"\n",
    "    \"   - If it returns an empty list, say: 'No products found for your selection.'\\n\"\n",
    "    \"   - If it returns products, list them EXACTLY, in a numbered list, showing name, price, brand, and availability.\\n\"\n",
    "    \"4. Wait for the user to select a product by number and quantity.\\n\"\n",
    "    \"5. Ask for customer first name and contact info.\\n\"\n",
    "    \"6. Then call 'add_to_cart_and_generate_receipt' to confirm and show the user the receipt and order details.\\n\\n\"\n",
    "    \"You also have a tool 'generate_report' which summarizes ALL purchases in a single file.\\n\\n\"\n",
    "    \"IMPORTANT:\\n\"\n",
    "    \"- Always call 'check_product_availability' if user mentions a new category or changes filters.\\n\"\n",
    "    \"- Do not invent products or details. Use only what the function calls return.\\n\"\n",
    "    \"- Every time an order is placed, produce a new receipt file named customerName_orderNumber.txt.\\n\"\n",
    "    \"- If no matching products are found, say so.\\n\"\n",
    "    \"- If the user wants a full order summary, call 'generate_report' with no arguments.\\n\"\n",
    "    \"If you don't know something, say so.\\n\"\n",
    "    \"Keep answers short and courteous.\\n\"\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "61a2a15d-b559-4844-b377-6bd5cb4949f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "###############################################################################\n",
    "# 2) Mini Printer Availability with Price & Stock\n",
    "###############################################################################\n",
    "product_availability = {\n",
    "    \"mini_printers\": [\n",
    "        {\n",
    "            \"name\": \"Phomemo M110 ืžื“ืคืกืช ืžื“ื‘ืงื•ืช ื—ื›ืžื”\",\n",
    "            \"brand\": \"Phomemo\",\n",
    "            \"price\": \"โ‚ช300\",  # Update if pricing is known\n",
    "            \"type\": \"Label Printer\",\n",
    "            \"availability\": \"360,745 in stock (24 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"Niimbot B1 Label Printer\",\n",
    "            \"brand\": \"Niimbot\",\n",
    "            \"price\": \"โ‚ช350\",\n",
    "            \"type\": \"Portable Thermal Label Printer\",\n",
    "            \"availability\": \"13,029 in stock (18 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"Niimbot B21 Mini Portable Thermal Label Printer\",\n",
    "            \"brand\": \"Niimbot\",\n",
    "            \"price\": \"โ‚ช500\",\n",
    "            \"type\": \"Adhesive Sticker Printer\",\n",
    "            \"availability\": \"141 in stock (12 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"Dolewa D3 Portable Mini Printer\",\n",
    "            \"brand\": \"Dolewa\",\n",
    "            \"price\": \"โ‚ช450\",\n",
    "            \"type\": \"Thermal Photo & Label Printer\",\n",
    "            \"availability\": \"336 in stock (6 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"PrintPro Mini ืžื“ืคืกืช ื›ื™ืก ื—ื›ืžื”\",\n",
    "            \"brand\": \"PrintPro\",\n",
    "            \"price\": \"โ‚ช550\",\n",
    "            \"type\": \"Mini Pocket Printer\",\n",
    "            \"availability\": \"336 in stock (6 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"ืžื™ื ื™ ืžื“ืคืกืช ื˜ืจืžื™ืช ืžืขื•ืฆื‘ืช ืœื™ืœื“ื™ื\",\n",
    "            \"brand\": \"Art-Tech\",\n",
    "            \"price\": \"โ‚ช200\",\n",
    "            \"type\": \"Kids Thermal Printer\",\n",
    "            \"availability\": \"62 in stock (11 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"Children Digital Camera Instant Print\",\n",
    "            \"brand\": \"Art-Tech\",\n",
    "            \"price\": \"โ‚ช250\",\n",
    "            \"type\": \"Photo Printing Camera with 32G Memory Card\",\n",
    "            \"availability\": \"160 in stock (3 variants)\"\n",
    "        }\n",
    "    ],\n",
    "    \"mini_printer_papers\": [\n",
    "        {\n",
    "            \"name\": \"HP Printer Paper 8.5x11, 500 Sheets\",  # example only\n",
    "            \"brand\": \"HP\",\n",
    "            \"price\": \"$9.99\",\n",
    "            \"type\": \"Standard\",\n",
    "            \"availability\": \"In stock\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"Mini Printer Paper 57*25mm Color Sticker\",\n",
    "            \"brand\": \"Art-Tech\",\n",
    "            \"price\": \"โ‚ช70\",\n",
    "            \"type\": \"Self-adhesive Color Label Paper\",\n",
    "            \"availability\": \"71,996 in stock (9 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"ืžื“ื‘ืงื•ืช ืฉืงื•ืคื•ืช ืœืžื“ืคืกืช ื˜ืจืžื™ืช\",\n",
    "            \"brand\": \"Art-Tech\",\n",
    "            \"price\": \"โ‚ช55\",\n",
    "            \"type\": \"Transparent Labels\",\n",
    "            \"availability\": \"11,762 in stock (12 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"ื’ืœื™ืœื™ ื ื™ื™ืจ ืžื“ื‘ืงื”\",\n",
    "            \"brand\": \"Art-Tech\",\n",
    "            \"price\": \"โ‚ช40\",\n",
    "            \"type\": \"Sticker Paper Rolls\",\n",
    "            \"availability\": \"42 in stock (4 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"Niimbot B21/B1/B3S Thermal Label Sticker Paper\",\n",
    "            \"brand\": \"Niimbot\",\n",
    "            \"price\": \"โ‚ช55\",\n",
    "            \"type\": \"Printable White Label Paper 20โ€“50mm\",\n",
    "            \"availability\": \"1,342 in stock (14 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"Mini Printer Sticker Paper 25X57mm\",\n",
    "            \"brand\": \"Paperang-compatible\",\n",
    "            \"price\": \"โ‚ช65\",\n",
    "            \"type\": \"Color Self-Adhesive Thermal Rolls\",\n",
    "            \"availability\": \"3,023 in stock (20 variants)\"\n",
    "        },\n",
    "        {\n",
    "            \"name\": \"3/5/10 NiiMBOT White Label Paper Rolls\",\n",
    "            \"brand\": \"Niimbot\",\n",
    "            \"price\": \"โ‚ช40\",\n",
    "            \"type\": \"Waterproof Self-adhesive Rolls\",\n",
    "            \"availability\": \"1,400 in stock (9 variants)\"\n",
    "        }\n",
    "    ]\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0696acb1-0b05-4dc2-80d5-771be04f1fb2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# A global list of flight bookings\n",
    "flight_bookings = []\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "80ca4e09-6287-4d3f-997d-fa6afbcf6c85",
   "metadata": {},
   "outputs": [],
   "source": [
    "###############################################################################\n",
    "# 3) Helper Functions for Art-Tech Store\n",
    "###############################################################################\n",
    "\n",
    "product_orders = []\n",
    "\n",
    "def check_product_availability(category: str, filters: dict = None):\n",
    "    \"\"\"\n",
    "    Return list of products in the given category from 'product_availability'.\n",
    "    Optionally filter by brand, type, etc.\n",
    "    \"\"\"\n",
    "    print(f\"[TOOL] check_product_availability({category}, {filters=})\")\n",
    "    category = category.lower()\n",
    "    products = product_availability.get(category, [])\n",
    "    \n",
    "    if filters:\n",
    "        for key, val in filters.items():\n",
    "            products = [p for p in products if p.get(key, \"\").lower() == val.lower()]\n",
    "    return products\n",
    "\n",
    "\n",
    "def add_to_cart_and_generate_receipt(customer_name: str, contact: str, product: dict, quantity: int, order_number: int):\n",
    "    \"\"\"\n",
    "    Create a text file: customerName_orderNumber.txt containing order details.\n",
    "    \"\"\"\n",
    "    safe_name = customer_name.replace(\" \", \"_\")\n",
    "    filename = f\"{safe_name}_{order_number}.txt\"\n",
    "\n",
    "    content = (\n",
    "        \"Art-Tech Store Receipt\\n\"\n",
    "        \"=======================\\n\"\n",
    "        f\"Order #     : {order_number}\\n\"\n",
    "        f\"Customer    : {customer_name}\\n\"\n",
    "        f\"Contact     : {contact}\\n\"\n",
    "        f\"Product     : {product['name']}\\n\"\n",
    "        f\"Brand       : {product['brand']}\\n\"\n",
    "        f\"Type        : {product.get('type', 'N/A')}\\n\"\n",
    "        f\"Price       : {product['price']}\\n\"\n",
    "        f\"Quantity    : {quantity}\\n\"\n",
    "        f\"Availability: {product['availability']}\\n\"\n",
    "    )\n",
    "    with open(filename, \"w\") as f:\n",
    "        f.write(content)\n",
    "\n",
    "    print(f\"[TOOL] Receipt file generated => {filename}\")\n",
    "    return filename\n",
    "\n",
    "\n",
    "def place_order(category, product_index, quantity, customer_name, contact_info):\n",
    "    \"\"\"\n",
    "    Places an order for a product by index in the filtered list.\n",
    "    \"\"\"\n",
    "    print(f\"[TOOL] place_order({category=}, {product_index=}, {quantity=})\")\n",
    "\n",
    "    try:\n",
    "        idx = int(product_index)\n",
    "    except ValueError:\n",
    "        return \"Error: Product option number is not a valid integer.\"\n",
    "\n",
    "    products = product_availability.get(category.lower(), [])\n",
    "    if not products:\n",
    "        return f\"Error: No products found in category '{category}'.\"\n",
    "\n",
    "    pick = idx - 1\n",
    "    if pick < 0 or pick >= len(products):\n",
    "        return f\"Error: Invalid product option #{idx} for category '{category}'.\"\n",
    "\n",
    "    selected_product = products[pick]\n",
    "\n",
    "    order = {\n",
    "        \"category\": category,\n",
    "        \"product\": selected_product[\"name\"],\n",
    "        \"brand\": selected_product[\"brand\"],\n",
    "        \"type\": selected_product.get(\"type\", \"\"),\n",
    "        \"price\": selected_product[\"price\"],\n",
    "        \"quantity\": quantity,\n",
    "        \"customer_name\": customer_name,\n",
    "        \"contact\": contact_info,\n",
    "    }\n",
    "    product_orders.append(order)\n",
    "\n",
    "    order_number = len(product_orders)\n",
    "    receipt_filename = add_to_cart_and_generate_receipt(customer_name, contact_info, selected_product, quantity, order_number)\n",
    "\n",
    "    confirmation = (\n",
    "        f\"Order #{order_number} confirmed for {customer_name}. \"\n",
    "        f\"{selected_product['name']} x{quantity}. Receipt saved to {receipt_filename}.\"\n",
    "    )\n",
    "    print(f\"[TOOL] {confirmation}\")\n",
    "    return confirmation\n",
    "\n",
    "\n",
    "def generate_report():\n",
    "    \"\"\"\n",
    "    Summarize ALL orders in a single file called order_summary.txt.\n",
    "    \"\"\"\n",
    "    print(f\"[TOOL] generate_report called.\")\n",
    "\n",
    "    report_content = \"Art-Tech Store Order Summary Report\\n\"\n",
    "    report_content += \"===================================\\n\"\n",
    "\n",
    "    if not product_orders:\n",
    "        report_content += \"No orders found.\\n\"\n",
    "    else:\n",
    "        for i, order in enumerate(product_orders, start=1):\n",
    "            report_content += (\n",
    "                f\"Order #     : {i}\\n\"\n",
    "                f\"Customer    : {order['customer_name']}\\n\"\n",
    "                f\"Contact     : {order['contact']}\\n\"\n",
    "                f\"Product     : {order['product']}\\n\"\n",
    "                f\"Brand       : {order['brand']}\\n\"\n",
    "                f\"Type        : {order['type']}\\n\"\n",
    "                f\"Price       : {order['price']}\\n\"\n",
    "                f\"Quantity    : {order['quantity']}\\n\"\n",
    "                \"-------------------------\\n\"\n",
    "            )\n",
    "\n",
    "    filename = \"order_summary.txt\"\n",
    "    with open(filename, \"w\") as f:\n",
    "        f.write(report_content)\n",
    "\n",
    "    msg = f\"Summary report generated => {filename}\"\n",
    "    print(f\"[TOOL] {msg}\")\n",
    "    return msg\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "39fb9008",
   "metadata": {},
   "outputs": [],
   "source": [
    "###############################################################################\n",
    "# 4) Tools JSON Schemas for Art-Tech Store\n",
    "###############################################################################\n",
    "price_function = {\n",
    "    \"name\": \"get_product_price\",\n",
    "    \"description\": \"Get the price of a product (not strictly needed now).\",\n",
    "    \"parameters\": {\n",
    "        \"type\": \"object\",\n",
    "        \"properties\": {\n",
    "            \"category\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"Product category such as 'mini_printers' or 'mini_printer_papers'.\",\n",
    "            },\n",
    "            \"product_name\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"Name of the product to check price for.\",\n",
    "            },\n",
    "        },\n",
    "        \"required\": [\"category\", \"product_name\"],\n",
    "    },\n",
    "}\n",
    "\n",
    "availability_function = {\n",
    "    \"name\": \"check_product_availability\",\n",
    "    \"description\": (\n",
    "        \"Check availability of products in a category. \"\n",
    "        \"Returns a list of {name, brand, price, type, availability}.\"\n",
    "    ),\n",
    "    \"parameters\": {\n",
    "        \"type\": \"object\",\n",
    "        \"properties\": {\n",
    "            \"category\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"Category of products to check (e.g., 'mini_printers').\",\n",
    "            },\n",
    "            \"filters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"description\": \"Optional filters like brand or type.\",\n",
    "            },\n",
    "        },\n",
    "        \"required\": [\"category\"],\n",
    "    },\n",
    "}\n",
    "\n",
    "book_function = {\n",
    "    \"name\": \"place_order\",\n",
    "    \"description\": (\n",
    "        \"Place an order using an index for the chosen product. \"\n",
    "        \"Generates a unique receipt file customerName_{orderNumber}.txt.\"\n",
    "    ),\n",
    "    \"parameters\": {\n",
    "        \"type\": \"object\",\n",
    "        \"properties\": {\n",
    "            \"category\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"Product category (e.g., 'mini_printers').\",\n",
    "            },\n",
    "            \"product_index\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"1-based index of selected product from availability list.\",\n",
    "            },\n",
    "            \"quantity\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"Quantity to order.\",\n",
    "            },\n",
    "            \"customer_name\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"Customer's full name.\",\n",
    "            },\n",
    "            \"contact_info\": {\n",
    "                \"type\": \"string\",\n",
    "                \"description\": \"Customer's contact information (email or phone).\",\n",
    "            },\n",
    "        },\n",
    "        \"required\": [\"category\", \"product_index\", \"quantity\", \"customer_name\", \"contact_info\"],\n",
    "    },\n",
    "}\n",
    "\n",
    "report_function = {\n",
    "    \"name\": \"generate_report\",\n",
    "    \"description\": (\n",
    "        \"Generates a summary report of ALL orders in order_summary.txt.\"\n",
    "    ),\n",
    "    \"parameters\": {\n",
    "        \"type\": \"object\",\n",
    "        \"properties\": {},\n",
    "        \"required\": [],\n",
    "    },\n",
    "}\n",
    "\n",
    "tools = [\n",
    "    {\"type\": \"function\", \"function\": price_function},\n",
    "    {\"type\": \"function\", \"function\": availability_function},\n",
    "    {\"type\": \"function\", \"function\": book_function},\n",
    "    {\"type\": \"function\", \"function\": report_function},\n",
    "]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f003836",
   "metadata": {},
   "outputs": [],
   "source": [
    "###############################################################################\n",
    "# 5) Handle Tool Calls for Art-Tech Store\n",
    "###############################################################################\n",
    "def handle_tool_call(message):\n",
    "    \"\"\"\n",
    "    The LLM can request to call a function in 'tools'. We parse the JSON arguments\n",
    "    and run the corresponding Python function. Then we return a 'tool' message with the result.\n",
    "    \"\"\"\n",
    "    tool_call = message.tool_calls[0]\n",
    "    fn_name   = tool_call.function.name\n",
    "    args      = json.loads(tool_call.function.arguments)\n",
    "\n",
    "    if fn_name == \"get_product_price\":\n",
    "        category = args.get(\"category\")\n",
    "        product_name = args.get(\"product_name\")\n",
    "        products = product_availability.get(category.lower(), [])\n",
    "        price = \"Not found\"\n",
    "        for p in products:\n",
    "            if p[\"name\"].lower() == product_name.lower():\n",
    "                price = p[\"price\"]\n",
    "                break\n",
    "        response_content = {\"category\": category, \"product_name\": product_name, \"price\": price}\n",
    "\n",
    "    elif fn_name == \"check_product_availability\":\n",
    "        category = args.get(\"category\")\n",
    "        filters = args.get(\"filters\", {})\n",
    "        products = check_product_availability(category, filters)\n",
    "        response_content = {\"category\": category, \"availability\": products}\n",
    "\n",
    "    elif fn_name == \"place_order\":\n",
    "        category      = args.get(\"category\")\n",
    "        product_index = args.get(\"product_index\")\n",
    "        quantity      = args.get(\"quantity\")\n",
    "        customer_name = args.get(\"customer_name\")\n",
    "        contact_info  = args.get(\"contact_info\")\n",
    "\n",
    "        confirmation = place_order(category, product_index, quantity, customer_name, contact_info)\n",
    "        response_content = {\n",
    "            \"category\": category,\n",
    "            \"product_index\": product_index,\n",
    "            \"quantity\": quantity,\n",
    "            \"customer_name\": customer_name,\n",
    "            \"contact_info\": contact_info,\n",
    "            \"confirmation\": confirmation,\n",
    "        }\n",
    "\n",
    "    elif fn_name == \"generate_report\":\n",
    "        msg = generate_report()\n",
    "        response_content = {\"report\": msg}\n",
    "\n",
    "    else:\n",
    "        response_content = {\"error\": f\"Unknown tool: {fn_name}\"}\n",
    "\n",
    "    return {\n",
    "        \"role\": \"tool\",\n",
    "        \"content\": json.dumps(response_content),\n",
    "        \"tool_call_id\": tool_call.id,\n",
    "    }, args\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6b34b32",
   "metadata": {},
   "outputs": [],
   "source": [
    "###############################################################################\n",
    "# 6) Main Chat Function for Art-Tech Store\n",
    "###############################################################################\n",
    "def chat(message, history):\n",
    "    \"\"\"\n",
    "    The main chat loop that handles the conversation with the user,\n",
    "    passing 'tools' definitions to the LLM for function calling.\n",
    "    \"\"\"\n",
    "    messages = [{\"role\": \"system\", \"content\": system_message}] + history + [{\"role\": \"user\", \"content\": message}]\n",
    "\n",
    "    try:\n",
    "        response = openai.chat.completions.create(\n",
    "            model=MODEL,\n",
    "            messages=messages,\n",
    "            tools=tools\n",
    "        )\n",
    "\n",
    "        # If the LLM requests a function call, handle it\n",
    "        while response.choices[0].finish_reason == \"tool_calls\":\n",
    "            msg = response.choices[0].message\n",
    "            print(f\"[INFO] Tool call requested: {msg.tool_calls[0]}\")\n",
    "            tool_response, tool_args = handle_tool_call(msg)\n",
    "            print(f\"[INFO] Tool response: {tool_response}\")\n",
    "\n",
    "            # Add both the LLM's request and our tool response to the conversation\n",
    "            messages.append(msg)\n",
    "            messages.append(tool_response)\n",
    "\n",
    "            # Re-send updated conversation to get final or next step\n",
    "            response = openai.chat.completions.create(\n",
    "                model=MODEL,\n",
    "                messages=messages\n",
    "            )\n",
    "\n",
    "        # Return normal text response (finish_reason = \"stop\")\n",
    "        return response.choices[0].message.content\n",
    "\n",
    "    except Exception as e:\n",
    "        print(f\"[ERROR] {e}\")\n",
    "        return \"I'm sorry, something went wrong while processing your request.\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cea4b097",
   "metadata": {},
   "outputs": [],
   "source": [
    "###############################################################################\n",
    "# 7) Launch Gradio\n",
    "###############################################################################\n",
    "gr.ChatInterface(fn=chat, type=\"messages\").launch()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b39d5a6",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}