Please fix this code to immediately return the generated response and send it to the html gui file, import asyncio
import websockets
import openai
import socket
import json

# Connect to LM Studio
openai.api_base = "http://localhost:8000/v1"
openai.api_key = "lm-studio"

# Function to get the local IP address
def get_local_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        # Doesn't have to be reachable
        s.connect(("10.254.254.254", 1))
        ip = s.getsockname()[0]
    except Exception:
        ip = "127.0.0.1"
    finally:
        s.close()
    return ip

connected_clients = set()
default_model = "TheBloke/phi-2-GGUF"

async def handler(websocket, path):
    local_ip = get_local_ip()
    server_info = f"ws://{local_ip}:8080"
    await websocket.send(f"Server Info: {server_info}")
    
    connected_clients.add(websocket)
    try:
        async for message in websocket:
            print(f"< {message}")

            if message == "!list_models":
                try:
                    models = openai.Model.list()
                    model_list = [model['id'] for model in models['data']]
                    await websocket.send(json.dumps({"type": "model_list", "data": model_list}))
                except Exception as e:
                    await websocket.send(json.dumps({"type": "error", "message": f"Error listing models: {e}"}))
            else:
                try:
                    # Parse the message to check for model switch command
                    parsed_message = json.loads(message)
                    if parsed_message.get("type") == "switch_model":
                        global default_model
                        default_model = parsed_message["model_id"]
                        await websocket.send(json.dumps({"type": "info", "message": f"Switched to model {default_model}"}))
                    else:
                        response = openai.ChatCompletion.create(
                            model=default_model,
                            messages=[
                                {"role": "user", "content": parsed_message["message"].strip()}
                            ],
                            temperature=0.7,
                            stream=True  # Enable streaming
                        )

                        async def stream_response(response):
                            current_word = ''
                            for chunk in response:
                                if 'content' in chunk['choices'][0]['delta']:
                                    token = chunk['choices'][0]['delta']['content']
                                    print(f"> {token}", end='')

                                    # Check if the token ends the current word
                                    if token.endswith(" ") or token.endswith("\n"):
                                        current_word += token
                                        await asyncio.gather(*[client.send(json.dumps({"type": "response", "data": current_word})) for client in connected_clients if client.open])
                                        current_word = ''
                                    else:
                                        current_word += token

                        await stream_response(response)

                except Exception as e:
                    print(f"Error during LM Studio interaction: {e}")
                    await websocket.send(json.dumps({"type": "error", "message": f"Error: {e}"}))
    finally:
        connected_clients.remove(websocket)

async def main():
    async with websockets.serve(handler, "0.0.0.0", 8080):  # Bind to all interfaces
        print("Server started at ws://0.0.0.0:8080")
        await asyncio.Future()  # Run forever

if __name__ == "__main__":
    asyncio.run(main())