import os import gradio as gr import openai from dotenv import load_dotenv # Load environment variables load_dotenv() openai.api_key = os.getenv("OPENAI_API_KEY") # System prompt for intent/entity extraction SYSTEM_PROMPT = ( "You are a customer support assistant. " "For every user message, reply with a JSON object containing: " "'intent' (the user's intent), 'entities' (dictionary of extracted entities), " "and 'response' (your natural reply). " 'Example: {"intent": "order_status", "entities": {"order_number": "12345"}, "response": "Your order 12345 is being processed."} ' "If no entities, use an empty dictionary." ) REQUEST_LIMIT = 200 global_request_count = 0 # Chatbot function using OpenAI ChatGPT API (OpenAI Python v1.x) def chatbot(user_message, history): global global_request_count if global_request_count >= REQUEST_LIMIT: display = "[Request limit reached. No further requests will be processed.]" return history + [[user_message, display]] global_request_count += 1 if history is None: history = [] # Track known entities across conversation known_entities = {} import json import re # Extract entities from previous bot replies for _, bot in history: match = re.search(r"\{[\s\S]*\}", bot) if match: try: parsed = json.loads(match.group(0)) entities = parsed.get("entities", {}) if isinstance(entities, dict): known_entities.update(entities) except Exception: pass # Prepend known entities to user message if any if known_entities: entity_context = f"[Known entities: {json.dumps(known_entities)}] " user_message = entity_context + user_message # Prepare messages for OpenAI API messages = [{"role": "system", "content": SYSTEM_PROMPT}] for user, bot in history: messages.append({"role": "user", "content": user}) messages.append({"role": "assistant", "content": bot}) messages.append({"role": "user", "content": user_message}) try: response = openai.chat.completions.create( model="gpt-4.1-mini", messages=messages, max_completion_tokens=256, temperature=0.7, ) raw_content = response.choices[0].message.content.strip() # Try to parse JSON try: # Extract JSON from code block or text match = re.search(r"\{[\s\S]*\}", raw_content) if match: json_str = match.group(0) parsed = json.loads(json_str) display = ( f"**Intent:** {parsed.get('intent','')}\n" f"**Entities:** {parsed.get('entities','')}\n" f"**Bot:** {parsed.get('response','')}" ) else: display = f"[Could not parse intent/entities]\n{raw_content}" except Exception: display = f"[Could not parse intent/entities]\n{raw_content}" except Exception as e: display = f"[Error: {str(e)}]" return history + [[user_message, display]] with gr.Blocks() as demo: gr.Markdown("# Customer Support Chatbot (MVP)") chatbot_ui = gr.Chatbot() msg = gr.Textbox(label="Your message") clear = gr.Button("Clear") def respond(user_message, chat_history): new_history = chatbot(user_message, chat_history) return "", new_history # Clear textbox after submit msg.submit(respond, [msg, chatbot_ui], [msg, chatbot_ui]) clear.click(lambda: ("", None), None, [msg, chatbot_ui], queue=False) demo.launch()