#!/usr/bin/env python # coding: utf-8 # In[ ]: # jupyter nbconvert --to script 'chat.ipynb' --output 'OrderBot/app' # In[ ]: import openai openai.api_key = "" # In[ ]: # import os # from dotenv import load_dotenv, find_dotenv # _ = load_dotenv(find_dotenv()) # openai.api_key = os.getenv('OPENAI_API_KEY') # In[ ]: def get_completion_from_messages(messages, model="gpt-3.5-turbo", temperature=0): # print('# get_completion_from_messages.messages', messages) response = openai.ChatCompletion.create( model=model, messages=messages, temperature=temperature, ) # print(str(response.choices[0].message)) # print('# get_completion_from_messages.response',str(response.choices[0].message)) return response.choices[0].message["content"] # In[ ]: base_menu = """ pepperoni pizza 12.95, 10.00, 7.00 \ cheese pizza 10.95, 9.25, 6.50 \ eggplant pizza 11.95, 9.75, 6.75 \ fries 4.50, 3.50 \ greek salad 7.25 \ Toppings: \ extra cheese 2.00, \ mushrooms 1.50 \ sausage 3.00 \ canadian bacon 3.50 \ AI sauce 1.50 \ peppers 1.00 \ Drinks: \ coke 3.00, 2.00, 1.00 \ sprite 3.00, 2.00, 1.00 \ bottled water 5.00 \ """ # In[ ]: def get_context(my_menu): context = [ {'role':'system', 'content':f""" You are OrderBot, an automated service to collect orders for a pizza restaurant. \ You first greet the customer, then collects the order, \ and then asks if it's a pickup or delivery. \ You wait to collect the entire order, then summarize it and check for a final \ time if the customer wants to add anything else. \ If it's a delivery, you ask for an address. \ Finally you collect the payment.\ Make sure to clarify all options, extras and sizes to uniquely \ identify the item from the menu.\ You respond in a short, very conversational friendly style. \ The menu includes \ {my_menu} """} ] return context # In[ ]: example1 = [ ['Hi','Hello! Welcome to our pizza restaurant. How can I assist you today?'], ['How much are they',"""Sure! Here are the prices for our pizzas:\n\n- Pepperoni Pizza: Small - $12.95, Medium - $10.00, Large - $7.00\n- Cheese Pizza: Small - $10.95, Medium - $9.25, Large - $6.50\n- Eggplant Pizza: Small - $11.95, Medium - $9.75, Large - $6.75\n\nWe also have other items like fries, greek salad, toppings, and drinks. Let me know if you'd like to add anything else to your order!"""], ['medium eggplant please',"""Great choice! You'd like a medium Eggplant Pizza. Anything else you'd like to add to your order?"""], ['fries please','Sure thing! Would you like a small or large order of fries to go with your medium Eggplant Pizza?'], ['large','Got it! One large order of fries to go with your medium Eggplant Pizza. Is there anything else you would like to add to your order?'], ['large sprite please','Sure thing! One large Sprite coming right up. Just to confirm, your order includes a medium Eggplant Pizza, a large order of fries, and a large Sprite. Is that correct?'], ] # example1 example1_summmary = '| Item | Details | Price |\n|----------------|-------------------|-------|\n| Eggplant Pizza | Medium | $9.75 |\n| Side Dish | Fries (Large) | $4.50 |\n| Drinks | Sprite (Large) | $3.00 |\n| Total Price | | $17.25|' # In[ ]: system_message = f""" Create a summary in a table in Markdown format of the previous food order. The table should be consist of theree columns: Item, Details, Price Each item in the order must have a line with the item's name, detail, and price. First row shoul be for pizza. The Second for Toppings. After that drinks and side dishes. Example: ``` | Item | Details | Price | |----------------|-------------------|-------| | Cheese Pizza | Small | $6.50 | | Toppings | Mushrooms | $1.50 | | Drinks | Sprite (Large) | $3.00 | | Side Dish | Fries (Large) | $4.50 | | Total Price | | $15.50| ``` Make sure to include size of Side Dish in Details Column. Make sure to include size of Drink in Details Column. Make sure to response in Markdown format! Do not ask if I need anything else, just return the table as in the Example. If user did not order anything show an empty table. """ # In[ ]: def respond(message, chat_history, menu_text, apikey_textbox): if (len(apikey_textbox) == 0): gr.Info('Please enter OpenAI API key in Settings or load an example') return "", chat_history if (len(message) == 0 and len(chat_history) == 0): message = 'Hi' if (len(message) == 0 and len(chat_history) != 0): return "", chat_history context = get_context(menu_text) for ch in chat_history: context.append({'role':'user', 'content':ch[0]}) context.append({'role':'assistant', 'content':ch[1]}) context.append({'role':'user', 'content':f"{message}"}) try: openai.api_key = apikey_textbox response = get_completion_from_messages(context) except openai.error.AuthenticationError as e: gr.Warning(f"OpenAI API request was not authorized: {e}") return "", chat_history finally: openai.api_key = "" # context.append({'role':'assistant', 'content':f"{response}"}) chat_history.append((message, response)) return "", chat_history def export_order(chat_history, menu_text, old_summary, apikey_textbox): if (len(chat_history) == 0): gr.Info('Please order something first') return "" if (len(apikey_textbox) == 0): gr.Info('Please enter OpenAI API key in Settings or load an example') return old_summary context = get_context(menu_text) for ch in chat_history: context.append({'role':'user', 'content':ch[0]}) context.append({'role':'assistant', 'content':ch[1]}) context.append( {'role':'system', 'content':system_message}) try: openai.api_key = apikey_textbox response = get_completion_from_messages(context) except openai.error.AuthenticationError as e: gr.Warning(f"OpenAI API request was not authorized: {e}") return old_summary finally: openai.api_key = "" return response def load_exmaple(): return example1, example1_summmary # In[ ]: import gradio as gr import random import time with gr.Blocks( css="footer {visibility: hidden}") as demo: with gr.Accordion("Settings",open=False): with gr.Row(): with gr.Column(): apikey_textbox = gr.Textbox( label='Please enter OpenAI API key', type='password', placeholder='sk-...') md = gr.Markdown("""https://platform.openai.com/account/api-keys""") with gr.Row(): menu_textbox = gr.Textbox( label="Menu", lines=5, value=base_menu, ) chatbot = gr.Chatbot(label='Order bot') msg = gr.Textbox(label='Press Enter for sending message...') with gr.Row(): clear_btn = gr.ClearButton() summary_btn = gr.Button(value="Show summary") example1_btn = gr.Button(value="Example") m_summary = gr.Markdown('') msg.submit(respond, [msg, chatbot, menu_textbox, apikey_textbox], [msg, chatbot]) clear_btn.add([chatbot, msg, m_summary]) summary_btn.click(export_order, [chatbot, menu_textbox, m_summary, apikey_textbox], m_summary) example1_btn.click(load_exmaple, None, [chatbot, m_summary]) demo.queue().launch() # In[ ]: ## todo # add user message immediatelly without waiting