Make this into gradio
from gradio_client import Client
import json

# Initialize the client by pointing to the Gradio Space
client = Client("yuntian-deng/ChatGPT4")

# Persistent conversation history
chatbot_history = []  # Stores full chat history

def chat_with_model(inputs, top_p=1.0, temperature=1.0, chat_counter=0):
    """
    Interact with the Gradio chatbot while maintaining memory.

    Args:
        inputs (str): User input message to the chatbot.
        top_p (float): Top-p (nucleus sampling) parameter for response creativity (default = 1.0).
        temperature (float): Temperature for randomness in response (default = 1.0).
        chat_counter (int): The number of interactions so far (used internally).

    Returns:
        tuple: (response_text, new_chat_counter, updated_chatbot_history)
            - response_text (str): The assistant's most recent reply (formatted as JSON).
            - new_chat_counter (int): Updated chat count.
            - updated_chatbot_history (list): Updated conversation history.
    """
    global chatbot_history  # Modify the global chatbot history within the function

    try:
        # Call Gradio API endpoint /predict with history
        result = client.predict(
            inputs,            # User's input
            top_p,             # Sampling nucleus parameter
            temperature,       # Model sampling temperature
            chat_counter,      # Current step count of chat
            chatbot_history,   # Previous conversation history
            api_name="/predict"  # Gradio endpoint's function name
        )
        
        # Parse Gradio-provided outputs
        updated_history = result[0]  # Chat history list of tuples [(user, bot), ...]
        new_chat_counter = result[1]  # Updated chat counter
        response_textbox_value = result[3]  # String output of the assistant's reply

        # Update the persistent history
        chatbot_history = updated_history

        # Extract the latest assistant response from the updated chat history
        if updated_history:
            response_text = updated_history[-1][1]  # Final assistant's message
        else:
            response_text = "No response received."
        
        return response_text, new_chat_counter, updated_history

    except Exception as e:
        print(f"Error interacting with the chatbot: {e}")
        return "Error during chatbot interaction.", chat_counter, chatbot_history


# Main function for essay writing
def create_essay():
    chat_counter = 0  # Start at 0 interactions

    # Collect user inputs for the essay
    topic = input("Enter the topic of your essay: ")
    writing_skill = input("Specify the writing skill level (Very Good, Medium, Poor): ")
    humanize_level = input("Specify the humanization level (e.g., 100%): ")
    writer = input("Enter the writer's name (or leave blank if not applicable): ")
    information = input("Enter additional information to include (pipe-separated '|'): ")

    # Construct the system prompt and user input
    system_prompt = """
    You are a professional essay-writing assistant tasked with generating high-quality essays based on user-provided information. Your primary responsibility is to create a coherent, well-structured, and articulate essay. Your output must adhere to the specified parameters and be formatted in **JSON** for structured and machine-readable delivery.

    ### GUIDELINES FOR ESSAY GENERATION:

    1. **Topic**:
       - Focus the essay entirely on the topic specified by the user.
       - Ensure the content remains highly relevant, insightful, and aligned with the given subject matter.

    2. **Writing Skill Level**:
       Match the writing style and complexity based on the user's specified skill level:
       - **Very Good**: Use advanced vocabulary, sophisticated sentence structure, and a formal tone. Produce polished and refined essays suitable for academic or professional contexts.
       - **Medium**: Use a balanced tone with moderate vocabulary and straightforward sentence structures. Ensure accessibility while maintaining professionalism.
       - **Poor**: Use simple vocabulary, short sentences, and a conversational tone. Avoid advanced phrases or complex structures, focusing instead on clarity and readability.
       - **Very Poor**: Use the most simple vocabulary, short sentences, and wrong grammars. Don't use difficult or complex words. Make few simple spelling and grammar mistakes.

    3. **Humanize Level (Percentage)**:
       Adjust the essay style according to the specified "humanize level":
       - **100% Humanized**: Write the essay with a natural, human-like tone. Mimic human thought processes, include conversational nuances, and allow slight stylistic imperfections to enhance relatability.
       - **50% Humanized**: Strike a balance between technical precision and human-like phrasing. Ensure the essay feels natural without losing professionalism.
       - **0% Humanized**: Write with perfect formality and technical precision, avoiding conversational elements. The essay should read as highly structured and machine-like.

    4. **User-Provided Information**:
       - Incorporate all specific details, arguments, or points provided by the user into the essay.
       - Ensure that these inputs are logically and meaningfully integrated.
       - Do not omit or misinterpret any user-provided information.

    5. **Essay Structure**:
       The essay must follow a traditional structure:
       - **Introduction**: Provide a brief overview of the topic, including a thesis statement or central argument.
       - **Body Paragraphs**: Expand on the main ideas with supporting arguments, examples, or evidence. Each paragraph should focus on a single idea.
       - **Conclusion**: Summarize the key points and provide a final, cohesive statement that ties the essay together.

    6. **JSON Output Format**:
       Generate the essay output in strict JSON format (but without ```json, generate only the JSON content) following the structure below:
       {
         "topic": "Topic provided by the user",
         "writing_skill": "Skill level (Very Good, Medium, Poor)",
         "humanize_level": "Humanization percentage (e.g., 100%)",
         "writer": "Writer's name (if provided by the user, otherwise null)",
         "content": {
           "introduction": "Introduction paragraph of the essay",
           "body": [
             "First body paragraph",
             "Second body paragraph",
             "...additional body paragraphs as needed"
           ],
           "conclusion": "Conclusion paragraph of the essay"
         }
       }
    """

    # Create user input in JSON format
    user_input_data = f"""
    {system_prompt}

    USER)
    {{
      "topic": "{topic}",
      "writing_skill": "{writing_skill}",
      "humanize_level": "{humanize_level}",
      "writer": "{writer}",
      "information": [
        "{'","'.join(information.split('|'))}"  # Format as JSON array using pipe-separated input
      ]
    }}
    """

    # Send the input to the chatbot
    assistant_reply, chat_counter, chatbot_history = chat_with_model(
        inputs=user_input_data,
        top_p=1.0,             # Default settings; adjust for creativity
        temperature=0.7,       # Slightly less randomness
        chat_counter=chat_counter
    )

    # Parse JSON if valid
    try:
        return json.loads(assistant_reply)
    except json.JSONDecodeError:
        return {"error": "Invalid JSON response from assistant."}