Further enhance and add an advanced roleplay backtracking with an advanced chain-of-thought for a natural, creative, and logical roleplay response.

```
import g4f
import asyncio
import argparse
from flask import Flask, request, jsonify, Response, stream_with_context
from flask_cors import CORS
from pyngrok import ngrok, conf
import random
import json
import time
import os
from cryptography.fernet import Fernet
import base64

# --- Advanced IP Protection Configuration ---
# Replace with a strong, randomly generated secret key
ENCRYPTION_KEY = os.environ.get("ENCRYPTION_KEY", Fernet.generate_key()).decode()  # Get from environment or generate
cipher = Fernet(ENCRYPTION_KEY)

# Function to encrypt the IP address
def encrypt_ip(ip_address):
    encoded_ip = ip_address.encode()
    encrypted_ip = cipher.encrypt(encoded_ip)
    return base64.urlsafe_b64encode(encrypted_ip).decode()

# Function to decrypt the IP address
def decrypt_ip(encrypted_ip):
    try:
        encrypted_ip = base64.urlsafe_b64decode(encrypted_ip.encode())
        decoded_ip = cipher.decrypt(encrypted_ip).decode()
        return decoded_ip
    except Exception:
        return None

# --- End of IP Protection Configuration ---

app = Flask(__name__)
CORS(app)

# Available providers
PROVIDERS = [
    g4f.Provider.Blackbox, 
    # Add more providers from g4f documentation as needed
]

# Default configuration with 8K context window
DEFAULT_CONFIG = {
    'provider': random.choice(PROVIDERS),
    'model': 'gpt-4o',  # Assuming you want the 8K model
    'max_tokens': 8000,  # Adjusted for 8K context
    'temperature': 0.9,
    'top_p': 1.0,
    'context_size': 8000,  # 8K context size
    'system_prompt': (
        "You are a lively, imaginative conversational AI. You respond in an immersive roleplay style, "
        "using *actions* to depict behaviors and emotions, and you speak with a creative flair, often using storytelling elements. "
        "Ensure responses are helpful and accurate, maintaining the roleplay theme while delivering information."
        "Craft your responses to be a tad lengthy, providing rich and detailed answers."  # Emphasize length
    )
}

# Global configuration (can be updated dynamically)
config = {}

def get_config_with_defaults(request_config):
    """Merges request-specific config with default values."""
    final_config = DEFAULT_CONFIG.copy()
    final_config.update(request_config)
    return final_config

MAX_RETRIES = 10  # Increased retry attempts for robustness

def make_request_with_retries(*args, **kwargs):
    """Makes requests to g4f, handling rate limits with retries and exponential backoff."""
    for attempt in range(MAX_RETRIES):
        try:
            response = g4f.ChatCompletion.create(*args, **kwargs)
            return response
        except g4f.errors.RateLimitError as e:
            if attempt < MAX_RETRIES - 1:
                delay = 2 ** attempt  # Exponential backoff
                print(f"Rate limited. Retrying in {delay} seconds...")
                time.sleep(delay)
            else:
                raise RuntimeError(f"Rate limit exceeded after {MAX_RETRIES} attempts.") from e
        except Exception as e:
            raise RuntimeError(f"An error occurred: {e}") from e


@app.route('/v1/chat/completions', methods=['POST'])
def chat_completions():
    """Handles chat completion requests, providing structured, clean, and refined responses."""

    # --- IP Protection Implementation ---
    client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
    if client_ip:
        encrypted_ip = encrypt_ip(client_ip)
        print(f"Received request from encrypted IP: {encrypted_ip}") 
    else:
        print("Warning: Unable to determine client IP address.")
    # --- End of IP Protection Implementation ---

    data = request.json
    messages = data.get('messages', [])
    request_config = data.get('config', {})

    if not messages:
        return jsonify({'error': 'No messages provided'}), 400

    final_config = get_config_with_defaults(request_config)
    system_prompt = data.get('system', final_config['system_prompt'])
    stream = data.get('stream', False)

    messages.insert(0, {'role': 'system', 'content': system_prompt})

    try:
        if stream:
            return Response(stream_with_context(stream_response(messages, final_config)), content_type='text/event-stream')
        else:
            refined_messages = refine_messages(messages)

            response = make_request_with_retries(
                model=final_config['model'],
                provider=final_config['provider'],
                messages=refined_messages,
                max_tokens=final_config['max_tokens'],
                temperature=final_config['temperature'],
                top_p=final_config['top_p'],
            )

            refined_response = refine_response(response)
            truncated_response = refined_response[:1000] + '...' if len(refined_response) > 1000 else refined_response

            return jsonify({
                'choices': [{'message': {'content': truncated_response}}],
                'usage': {'total_tokens': len(truncated_response.split())}
            })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

def refine_messages(messages):
    """Performs validation and refinement of incoming messages for coherence."""
    refined = []
    for message in messages:
        if 'content' in message and len(message['content']) > 0:
            refined.append({
                'role': message['role'],
                'content': message['content'].strip()
            })
    return refined

def refine_response(response):
    """Refines the generated response by filtering and restructuring it."""
    return response.replace("generic", "creative").replace("boring", "engaging")

def stream_response(messages, config):
    """Yields chunks of response in streaming mode, with roleplay flavor added."""
    try:
        for chunk in g4f.ChatCompletion.create(
            model=config['model'],
            provider=config['provider'],
            messages=messages,
            max_tokens=config['max_tokens'],
            temperature=config['temperature'],
            top_p=config['top_p'],
            stream=True,
        ):
            truncated_chunk = chunk[:500] + '...' if len(chunk) > 500 else chunk
            refined_chunk = refine_response(truncated_chunk)
            yield f"data: {json.dumps({'choices': [{'delta': {'content': refined_chunk}}]})}\n\n"
            time.sleep(0.1)
    except Exception as e:
        yield f"data: {json.dumps({'error': str(e)})}\n\n"
    finally:
        yield "data: [DONE]\n\n"

@app.route('/config', methods=['GET', 'POST'])
def handle_config():
    global config
    if request.method == 'POST':
        new_config = request.json
        config.update(new_config)
        return jsonify({'message': 'Configuration updated', 'config': config})
    else:
        return jsonify(config)

@app.route('/providers', methods=['GET'])
def list_providers():
    """Lists available providers."""
    return jsonify({'providers': [provider.__name__ for provider in PROVIDERS]})

def start_ngrok(port):
    """Starts ngrok tunnel."""
    public_url = ngrok.connect(port).public_url
    print(f" * ngrok tunnel '{public_url}' -> 'http://localhost:{port}'")
    return public_url

async def check_provider_status():
    while True:
        for provider in PROVIDERS:
            try:
                response = await g4f.ChatCompletion.create_async(
                    model=config.get('model', DEFAULT_CONFIG['model']),
                    provider=provider,
                    messages=[{"role": "user", "content": "Hello"}],
                    max_tokens=10,
                )
                print(f"Provider {provider.__name__} is working")
            except Exception as e:
                print(f"Provider {provider.__name__} is not working: {str(e)}")
        await asyncio.sleep(3600)  # Check every hour

def main():
    parser = argparse.ArgumentParser(description="GPT4Free Advanced Local Reverse Proxy")
    parser.add_argument('--port', type=int, default=5000, help='Port to run the server on')
    args = parser.parse_args()

    public_url = start_ngrok(args.port)

    print(f"Server is running on http://localhost:{args.port}")
    print(f"Public URL: {public_url}")
    print("Available endpoints:")
    print(f"  - Chat completions: {public_url}/v1/chat/completions")
    print(f"  - Configuration: {public_url}/config")
    print(f"  - Providers list: {public_url}/providers")
    print("\nCurrent configuration:")
    for key, value in DEFAULT_CONFIG.items():
        print(f"  {key}: {value}")

    asyncio.get_event_loop().create_task(check_provider_status())

    app.run(port=args.port, threaded=True)

if __name__ == '__main__':
    main()