2023-04-11 10:50:07 +00:00
######
# Project : GPT4ALL-UI
# Author : ParisNeo with the help of the community
# Supported by Nomic-AI
# Licence : Apache 2.0
# Description :
# A front end Flask application for llamacpp models.
# The official GPT4All Web ui
# Made by the community for the community
######
2023-04-20 17:30:03 +00:00
__author__ = " parisneo "
__github__ = " https://github.com/nomic-ai/gpt4all-ui "
__copyright__ = " Copyright 2023, "
__license__ = " Apache 2.0 "
2023-04-27 23:39:57 +00:00
import os
2023-04-27 14:53:13 +00:00
import logging
2023-04-06 19:12:49 +00:00
import argparse
2023-04-07 16:58:42 +00:00
import json
2023-04-06 19:12:49 +00:00
import re
2023-04-07 16:58:42 +00:00
import traceback
2023-04-24 20:02:50 +00:00
import threading
2023-04-08 10:25:40 +00:00
import sys
2023-04-30 20:40:19 +00:00
from pyaipersonality import AIPersonality
2023-04-15 11:30:08 +00:00
from pyGpt4All . db import DiscussionsDB , Discussion
2023-04-07 16:58:42 +00:00
from flask import (
Flask ,
Response ,
jsonify ,
render_template ,
request ,
stream_with_context ,
2023-04-08 17:55:33 +00:00
send_from_directory
2023-04-07 16:58:42 +00:00
)
2023-04-27 14:44:22 +00:00
from flask_socketio import SocketIO , emit
2023-04-08 17:55:33 +00:00
from pathlib import Path
2023-04-09 19:26:04 +00:00
import gc
2023-04-30 01:15:11 +00:00
from geventwebsocket . handler import WebSocketHandler
from gevent . pywsgi import WSGIServer
2023-04-07 16:58:42 +00:00
app = Flask ( " GPT4All-WebUI " , static_url_path = " /static " , static_folder = " static " )
2023-05-03 15:03:22 +00:00
socketio = SocketIO ( app , cors_allowed_origins = " * " , async_mode = ' gevent ' , ping_timeout = 30 , ping_interval = 15 )
2023-05-02 20:53:27 +00:00
2023-04-27 23:39:57 +00:00
app . config [ ' SECRET_KEY ' ] = ' secret! '
2023-04-27 14:53:13 +00:00
# Set the logging level to WARNING or higher
logging . getLogger ( ' socketio ' ) . setLevel ( logging . WARNING )
logging . getLogger ( ' engineio ' ) . setLevel ( logging . WARNING )
2023-04-27 23:39:57 +00:00
# Suppress Flask's default console output
log = logging . getLogger ( ' werkzeug ' )
log . setLevel ( logging . ERROR )
2023-04-27 06:52:00 +00:00
2023-04-09 19:26:04 +00:00
import time
2023-04-15 11:30:08 +00:00
from pyGpt4All . config import load_config , save_config
from pyGpt4All . api import GPT4AllAPI
2023-04-14 15:11:40 +00:00
import shutil
2023-04-16 21:22:09 +00:00
import markdown
2023-04-27 06:52:00 +00:00
2023-04-15 11:30:08 +00:00
class Gpt4AllWebUI ( GPT4AllAPI ) :
2023-04-27 06:52:00 +00:00
def __init__ ( self , _app , _socketio , config : dict , personality : dict , config_file_path ) - > None :
2023-04-15 11:30:08 +00:00
super ( ) . __init__ ( config , personality , config_file_path )
2023-04-07 16:58:42 +00:00
self . app = _app
2023-04-22 17:14:25 +00:00
self . cancel_gen = False
2023-04-27 06:52:00 +00:00
self . socketio = _socketio
2023-04-15 11:30:08 +00:00
2023-05-02 20:53:27 +00:00
if " use_new_ui " in self . config :
if self . config [ " use_new_ui " ] :
app . template_folder = " web/dist "
2023-04-08 17:55:33 +00:00
2023-04-20 17:30:03 +00:00
self . add_endpoint (
" /list_backends " , " list_backends " , self . list_backends , methods = [ " GET " ]
)
2023-04-10 08:27:25 +00:00
self . add_endpoint (
" /list_models " , " list_models " , self . list_models , methods = [ " GET " ]
)
2023-04-20 17:30:03 +00:00
self . add_endpoint (
" /list_personalities_languages " , " list_personalities_languages " , self . list_personalities_languages , methods = [ " GET " ]
)
self . add_endpoint (
" /list_personalities_categories " , " list_personalities_categories " , self . list_personalities_categories , methods = [ " GET " ]
)
2023-04-13 22:47:20 +00:00
self . add_endpoint (
" /list_personalities " , " list_personalities " , self . list_personalities , methods = [ " GET " ]
)
2023-04-14 00:10:22 +00:00
self . add_endpoint (
" /list_languages " , " list_languages " , self . list_languages , methods = [ " GET " ]
)
2023-04-10 08:27:25 +00:00
self . add_endpoint (
" /list_discussions " , " list_discussions " , self . list_discussions , methods = [ " GET " ]
)
2023-04-08 17:55:33 +00:00
2023-04-20 17:30:03 +00:00
self . add_endpoint ( " /set_personality_language " , " set_personality_language " , self . set_personality_language , methods = [ " GET " ] )
self . add_endpoint ( " /set_personality_category " , " set_personality_category " , self . set_personality_category , methods = [ " GET " ] )
2023-04-07 19:44:55 +00:00
2023-04-07 16:58:42 +00:00
self . add_endpoint ( " / " , " " , self . index , methods = [ " GET " ] )
2023-05-02 20:53:27 +00:00
self . add_endpoint ( " /<path:filename> " , " serve_static " , self . serve_static , methods = [ " GET " ] )
2023-04-10 08:27:25 +00:00
self . add_endpoint ( " /export_discussion " , " export_discussion " , self . export_discussion , methods = [ " GET " ] )
2023-04-07 16:58:42 +00:00
self . add_endpoint ( " /export " , " export " , self . export , methods = [ " GET " ] )
self . add_endpoint (
" /new_discussion " , " new_discussion " , self . new_discussion , methods = [ " GET " ]
)
2023-04-23 22:19:15 +00:00
self . add_endpoint ( " /stop_gen " , " stop_gen " , self . stop_gen , methods = [ " GET " ] )
2023-04-22 17:14:25 +00:00
2023-04-07 16:58:42 +00:00
self . add_endpoint ( " /rename " , " rename " , self . rename , methods = [ " POST " ] )
2023-05-04 14:38:03 +00:00
self . add_endpoint ( " /edit_title " , " edit_title " , self . edit_title , methods = [ " POST " ] )
2023-04-07 16:58:42 +00:00
self . add_endpoint (
2023-04-09 19:26:04 +00:00
" /load_discussion " , " load_discussion " , self . load_discussion , methods = [ " POST " ]
2023-04-07 16:58:42 +00:00
)
self . add_endpoint (
" /delete_discussion " ,
" delete_discussion " ,
self . delete_discussion ,
methods = [ " POST " ] ,
)
self . add_endpoint (
" /update_message " , " update_message " , self . update_message , methods = [ " GET " ]
)
2023-04-10 14:14:39 +00:00
self . add_endpoint (
" /message_rank_up " , " message_rank_up " , self . message_rank_up , methods = [ " GET " ]
)
self . add_endpoint (
" /message_rank_down " , " message_rank_down " , self . message_rank_down , methods = [ " GET " ]
)
2023-04-13 10:31:48 +00:00
self . add_endpoint (
" /delete_message " , " delete_message " , self . delete_message , methods = [ " GET " ]
)
2023-04-22 17:14:25 +00:00
self . add_endpoint (
" /set_backend " , " set_backend " , self . set_backend , methods = [ " POST " ]
)
2023-04-10 14:14:39 +00:00
2023-04-23 19:05:39 +00:00
self . add_endpoint (
" /set_model " , " set_model " , self . set_model , methods = [ " POST " ]
)
2023-04-07 21:22:17 +00:00
self . add_endpoint (
" /update_model_params " , " update_model_params " , self . update_model_params , methods = [ " POST " ]
)
2023-04-08 17:55:33 +00:00
self . add_endpoint (
2023-04-12 20:36:03 +00:00
" /get_config " , " get_config " , self . get_config , methods = [ " GET " ]
2023-04-08 17:55:33 +00:00
)
2023-04-11 20:56:15 +00:00
2023-04-11 23:34:50 +00:00
self . add_endpoint (
" /extensions " , " extensions " , self . extensions , methods = [ " GET " ]
)
self . add_endpoint (
" /training " , " training " , self . training , methods = [ " GET " ]
)
2023-04-13 10:31:48 +00:00
self . add_endpoint (
" /main " , " main " , self . main , methods = [ " GET " ]
)
self . add_endpoint (
" /settings " , " settings " , self . settings , methods = [ " GET " ]
)
2023-04-11 23:34:50 +00:00
2023-04-11 20:56:15 +00:00
self . add_endpoint (
" /help " , " help " , self . help , methods = [ " GET " ]
)
2023-04-27 14:44:22 +00:00
# Socket IO stuff
@socketio.on ( ' connect ' )
2023-04-27 23:39:57 +00:00
def connect ( ) :
2023-04-27 14:44:22 +00:00
print ( ' Client connected ' )
@socketio.on ( ' disconnect ' )
2023-04-27 23:39:57 +00:00
def disconnect ( ) :
2023-04-27 14:44:22 +00:00
print ( ' Client disconnected ' )
2023-04-27 23:39:57 +00:00
@socketio.on ( ' generate_msg ' )
def generate_msg ( data ) :
2023-04-27 14:44:22 +00:00
if self . current_discussion is None :
if self . db . does_last_discussion_have_messages ( ) :
self . current_discussion = self . db . create_discussion ( )
else :
self . current_discussion = self . db . load_last_discussion ( )
message = data [ " prompt " ]
message_id = self . current_discussion . add_message (
" user " , message , parent = self . current_message_id
)
message = data [ " prompt " ]
self . current_message_id = message_id
tpe = threading . Thread ( target = self . parse_to_prompt_stream , args = ( message , message_id ) )
tpe . start ( )
2023-04-27 23:39:57 +00:00
@socketio.on ( ' generate_msg_from ' )
def handle_connection ( data ) :
message_id = int ( data [ ' id ' ] )
message = data [ " prompt " ]
self . current_message_id = message_id
tpe = threading . Thread ( target = self . parse_to_prompt_stream , args = ( message , message_id ) )
tpe . start ( )
2023-04-27 14:44:22 +00:00
2023-04-11 20:56:15 +00:00
2023-04-20 17:30:03 +00:00
def list_backends ( self ) :
2023-04-24 19:24:18 +00:00
backends_dir = Path ( ' ./backends ' ) # replace with the actual path to the models folder
2023-04-24 21:58:50 +00:00
backends = [ f . stem for f in backends_dir . iterdir ( ) if f . is_dir ( ) and f . stem != " __pycache__ " ]
2023-04-20 17:30:03 +00:00
return jsonify ( backends )
2023-04-07 19:44:55 +00:00
2023-04-08 17:55:33 +00:00
def list_models ( self ) :
2023-05-02 14:49:13 +00:00
models = self . backend . list_models ( self . config )
2023-04-08 17:55:33 +00:00
return jsonify ( models )
2023-04-13 22:47:20 +00:00
2023-04-20 17:30:03 +00:00
def list_personalities_languages ( self ) :
personalities_languages_dir = Path ( f ' ./personalities ' ) # replace with the actual path to the models folder
personalities_languages = [ f . stem for f in personalities_languages_dir . iterdir ( ) if f . is_dir ( ) ]
return jsonify ( personalities_languages )
def list_personalities_categories ( self ) :
personalities_categories_dir = Path ( f ' ./personalities/ { self . config [ " personality_language " ] } ' ) # replace with the actual path to the models folder
personalities_categories = [ f . stem for f in personalities_categories_dir . iterdir ( ) if f . is_dir ( ) ]
return jsonify ( personalities_categories )
2023-04-13 22:47:20 +00:00
def list_personalities ( self ) :
2023-04-20 17:30:03 +00:00
personalities_dir = Path ( f ' ./personalities/ { self . config [ " personality_language " ] } / { self . config [ " personality_category " ] } ' ) # replace with the actual path to the models folder
2023-04-30 20:40:19 +00:00
personalities = [ f . stem for f in personalities_dir . iterdir ( ) if f . is_dir ( ) ]
2023-04-13 22:47:20 +00:00
return jsonify ( personalities )
2023-04-07 21:22:17 +00:00
2023-04-14 00:10:22 +00:00
def list_languages ( self ) :
lanuguages = [
{ " value " : " en-US " , " label " : " English " } ,
{ " value " : " fr-FR " , " label " : " Français " } ,
{ " value " : " ar-AR " , " label " : " العربية " } ,
{ " value " : " it-IT " , " label " : " Italiano " } ,
{ " value " : " de-DE " , " label " : " Deutsch " } ,
{ " value " : " nl-XX " , " label " : " Dutch " } ,
{ " value " : " zh-CN " , " label " : " 中國人 " }
]
return jsonify ( lanuguages )
2023-04-10 08:27:25 +00:00
def list_discussions ( self ) :
2023-04-10 14:14:39 +00:00
discussions = self . db . get_discussions ( )
return jsonify ( discussions )
2023-04-10 08:27:25 +00:00
2023-04-20 17:30:03 +00:00
def set_personality_language ( self ) :
lang = request . args . get ( ' language ' )
self . config [ ' personality_language ' ] = lang
return jsonify ( { ' success ' : True } )
def set_personality_category ( self ) :
category = request . args . get ( ' category ' )
self . config [ ' personality_category ' ] = category
return jsonify ( { ' success ' : True } )
2023-04-07 16:58:42 +00:00
def add_endpoint (
self ,
endpoint = None ,
endpoint_name = None ,
handler = None ,
methods = [ " GET " ] ,
* args ,
* * kwargs ,
) :
self . app . add_url_rule (
endpoint , endpoint_name , handler , methods = methods , * args , * * kwargs
)
2023-04-06 19:12:49 +00:00
def index ( self ) :
2023-04-17 15:59:36 +00:00
return render_template ( " index.html " )
2023-05-02 20:53:27 +00:00
def serve_static ( self , filename ) :
root_dir = os . getcwd ( )
if " use_new_ui " in self . config :
if self . config [ " use_new_ui " ] :
path = os . path . join ( root_dir , ' web/dist/ ' ) + " / " . join ( filename . split ( " / " ) [ : - 1 ] )
else :
path = os . path . join ( root_dir , ' static/ ' ) + " / " . join ( filename . split ( " / " ) [ : - 1 ] )
else :
path = os . path . join ( root_dir , ' static/ ' ) + " / " . join ( filename . split ( " / " ) [ : - 1 ] )
fn = filename . split ( " / " ) [ - 1 ]
return send_from_directory ( path , fn )
2023-04-06 19:12:49 +00:00
def format_message ( self , message ) :
# Look for a code block within the message
pattern = re . compile ( r " (```.*?```) " , re . DOTALL )
match = pattern . search ( message )
# If a code block is found, replace it with a <code> tag
if match :
code_block = match . group ( 1 )
message = message . replace ( code_block , f " <code> { code_block [ 3 : - 3 ] } </code> " )
# Return the formatted message
return message
def export ( self ) :
2023-04-10 08:27:25 +00:00
return jsonify ( self . db . export_to_json ( ) )
2023-04-06 19:12:49 +00:00
2023-04-10 08:27:25 +00:00
def export_discussion ( self ) :
2023-04-17 22:23:31 +00:00
return jsonify ( { " discussion_text " : self . get_discussion_to ( ) } )
2023-04-10 08:27:25 +00:00
2023-04-08 16:55:55 +00:00
2023-04-06 19:12:49 +00:00
def parse_to_prompt_stream ( self , message , message_id ) :
2023-04-07 16:58:42 +00:00
bot_says = " "
2023-04-06 19:12:49 +00:00
# send the message to the bot
print ( f " Received message : { message } " )
2023-04-27 23:39:57 +00:00
if self . current_discussion :
# First we need to send the new message ID to the client
response_id = self . current_discussion . add_message (
2023-04-30 20:40:19 +00:00
self . personality . name , " " , parent = message_id
2023-04-27 23:39:57 +00:00
) # first the content is empty, but we'll fill it at the end
socketio . emit ( ' infos ' ,
{
" type " : " input_message_infos " ,
2023-04-30 20:40:19 +00:00
" bot " : self . personality . name ,
" user " : self . personality . user_name ,
2023-04-28 09:19:57 +00:00
" message " : message , #markdown.markdown(message),
2023-04-27 23:39:57 +00:00
" id " : message_id ,
" response_id " : response_id ,
}
) ;
# prepare query and reception
self . discussion_messages = self . prepare_query ( message_id )
self . prepare_reception ( )
self . generating = True
# app.config['executor'] = ThreadPoolExecutor(max_workers=1)
# app.config['executor'].submit(self.generate_message)
2023-04-30 01:15:11 +00:00
print ( " ## Generating message ## " )
2023-04-27 23:39:57 +00:00
self . generate_message ( )
2023-04-30 01:15:11 +00:00
print ( )
2023-04-27 23:39:57 +00:00
print ( " ## Done ## " )
2023-04-30 01:15:11 +00:00
print ( )
# Send final message
self . socketio . emit ( ' final ' , { ' data ' : self . bot_says } )
2023-04-27 23:39:57 +00:00
self . current_discussion . update_message ( response_id , self . bot_says )
self . full_message_list . append ( self . bot_says )
self . cancel_gen = False
return bot_says
else :
2023-04-30 01:15:11 +00:00
#No discussion available
print ( )
2023-04-27 23:39:57 +00:00
print ( " ## Done ## " )
2023-04-30 01:15:11 +00:00
print ( )
2023-05-02 12:16:10 +00:00
self . cancel_gen = False
2023-04-27 23:39:57 +00:00
return " "
2023-04-13 21:53:13 +00:00
2023-04-27 23:39:57 +00:00
2023-04-23 22:19:15 +00:00
def stop_gen ( self ) :
2023-04-22 17:14:25 +00:00
self . cancel_gen = True
2023-05-02 09:02:59 +00:00
print ( " Stop generation received " )
2023-04-22 17:14:25 +00:00
return jsonify ( { " status " : " ok " } )
2023-04-06 19:12:49 +00:00
def rename ( self ) :
data = request . get_json ( )
2023-04-07 16:58:42 +00:00
title = data [ " title " ]
2023-04-10 14:15:12 +00:00
self . current_discussion . rename ( title )
2023-04-06 19:12:49 +00:00
return " renamed successfully "
2023-05-04 14:38:03 +00:00
def edit_title ( self ) :
data = request . get_json ( )
title = data [ " title " ]
discussion_id = data [ " id " ]
self . current_discussion = Discussion ( discussion_id , self . db )
self . current_discussion . rename ( title )
return " title renamed successfully "
2023-04-09 19:26:04 +00:00
def load_discussion ( self ) :
2023-04-07 21:22:17 +00:00
data = request . get_json ( )
2023-04-13 15:24:52 +00:00
if " id " in data :
discussion_id = data [ " id " ]
2023-04-13 19:40:46 +00:00
self . current_discussion = Discussion ( discussion_id , self . db )
2023-04-13 15:24:52 +00:00
else :
if self . current_discussion is not None :
discussion_id = self . current_discussion . discussion_id
2023-04-13 19:40:46 +00:00
self . current_discussion = Discussion ( discussion_id , self . db )
2023-04-13 15:24:52 +00:00
else :
2023-04-13 19:40:46 +00:00
self . current_discussion = self . db . create_discussion ( )
2023-04-07 21:22:17 +00:00
messages = self . current_discussion . get_messages ( )
2023-04-28 09:19:57 +00:00
#for message in messages:
# message["content"] = markdown.markdown(message["content"])
2023-04-07 21:22:17 +00:00
2023-04-20 17:30:03 +00:00
return jsonify ( messages ) , { ' Content-Type ' : ' application/json; charset=utf-8 ' }
2023-04-06 19:12:49 +00:00
def delete_discussion ( self ) :
data = request . get_json ( )
2023-04-07 16:58:42 +00:00
discussion_id = data [ " id " ]
2023-04-10 09:14:10 +00:00
self . current_discussion = Discussion ( discussion_id , self . db )
2023-04-06 19:12:49 +00:00
self . current_discussion . delete_discussion ( )
self . current_discussion = None
return jsonify ( { } )
2023-04-07 16:58:42 +00:00
2023-04-06 19:12:49 +00:00
def update_message ( self ) :
2023-04-10 14:14:39 +00:00
discussion_id = request . args . get ( " id " )
new_message = request . args . get ( " message " )
self . current_discussion . update_message ( discussion_id , new_message )
return jsonify ( { " status " : " ok " } )
def message_rank_up ( self ) :
discussion_id = request . args . get ( " id " )
new_rank = self . current_discussion . message_rank_up ( discussion_id )
return jsonify ( { " new_rank " : new_rank } )
def message_rank_down ( self ) :
discussion_id = request . args . get ( " id " )
new_rank = self . current_discussion . message_rank_down ( discussion_id )
return jsonify ( { " new_rank " : new_rank } )
2023-04-06 19:12:49 +00:00
2023-04-13 10:31:48 +00:00
def delete_message ( self ) :
discussion_id = request . args . get ( " id " )
2023-04-27 23:39:57 +00:00
if self . current_discussion is None :
return jsonify ( { " status " : False , " message " : " No discussion is selected " } )
else :
new_rank = self . current_discussion . delete_message ( discussion_id )
return jsonify ( { " status " : True , " new_rank " : new_rank } )
2023-04-13 10:31:48 +00:00
2023-04-06 19:12:49 +00:00
def new_discussion ( self ) :
2023-04-07 16:58:42 +00:00
title = request . args . get ( " title " )
2023-04-15 11:30:08 +00:00
timestamp = self . create_new_discussion ( title )
2023-04-24 21:11:32 +00:00
# app.config['executor'] = ThreadPoolExecutor(max_workers=1)
# app.config['executor'].submit(self.create_chatbot)
# target=self.create_chatbot()
2023-04-06 19:12:49 +00:00
# Return a success response
2023-04-30 20:40:19 +00:00
return json . dumps ( { " id " : self . current_discussion . discussion_id , " time " : timestamp , " welcome_message " : self . personality . welcome_message , " sender " : self . personality . name } )
2023-04-07 16:58:42 +00:00
2023-04-22 17:14:25 +00:00
def set_backend ( self ) :
data = request . get_json ( )
backend = str ( data [ " backend " ] )
if self . config [ ' backend ' ] != backend :
2023-04-23 19:05:39 +00:00
print ( " New backend selected " )
2023-04-22 17:14:25 +00:00
self . config [ ' backend ' ] = backend
2023-05-02 14:49:13 +00:00
backend_ = self . load_backend ( self . BACKENDS_LIST [ self . config [ " backend " ] ] )
models = backend_ . list_models ( self . config )
if len ( models ) > 0 :
self . backend = backend_
2023-04-22 17:14:25 +00:00
self . config [ ' model ' ] = models [ 0 ]
2023-04-24 21:58:50 +00:00
# Build chatbot
self . chatbot_bindings = self . create_chatbot ( )
2023-04-22 17:14:25 +00:00
return jsonify ( { " status " : " ok " } )
2023-04-23 22:19:15 +00:00
else :
return jsonify ( { " status " : " no_models_found " } )
2023-04-22 17:14:25 +00:00
2023-04-23 14:59:00 +00:00
return jsonify ( { " status " : " error " } )
2023-04-23 19:05:39 +00:00
def set_model ( self ) :
data = request . get_json ( )
model = str ( data [ " model " ] )
if self . config [ ' model ' ] != model :
print ( " New model selected " )
self . config [ ' model ' ] = model
2023-04-24 21:58:50 +00:00
# Build chatbot
self . chatbot_bindings = self . create_chatbot ( )
2023-04-23 19:05:39 +00:00
return jsonify ( { " status " : " ok " } )
return jsonify ( { " status " : " error " } )
2023-04-23 14:59:00 +00:00
2023-04-07 21:22:17 +00:00
def update_model_params ( self ) :
data = request . get_json ( )
2023-04-20 17:33:21 +00:00
backend = str ( data [ " backend " ] )
2023-04-08 17:55:33 +00:00
model = str ( data [ " model " ] )
2023-04-20 17:33:21 +00:00
personality_language = str ( data [ " personality_language " ] )
personality_category = str ( data [ " personality_category " ] )
2023-04-15 11:37:42 +00:00
personality = str ( data [ " personality " ] )
2023-04-20 17:33:21 +00:00
if self . config [ ' backend ' ] != backend or self . config [ ' model ' ] != model :
2023-04-08 17:55:33 +00:00
print ( " New model selected " )
2023-04-20 17:33:21 +00:00
self . config [ ' backend ' ] = backend
2023-04-12 20:36:03 +00:00
self . config [ ' model ' ] = model
2023-04-15 11:30:08 +00:00
self . create_chatbot ( )
2023-04-08 17:55:33 +00:00
2023-04-22 17:14:25 +00:00
self . config [ ' personality_language ' ] = personality_language
self . config [ ' personality_category ' ] = personality_category
self . config [ ' personality ' ] = personality
2023-04-20 17:33:21 +00:00
2023-04-30 20:40:19 +00:00
personality_fn = f " personalities/ { self . config [ ' personality_language ' ] } / { self . config [ ' personality_category ' ] } / { self . config [ ' personality ' ] } "
2023-04-22 17:14:25 +00:00
print ( f " Loading personality : { personality_fn } " )
2023-04-30 20:40:19 +00:00
self . personality = AIPersonality ( personality_fn )
2023-04-15 11:37:42 +00:00
2023-04-12 20:36:03 +00:00
self . config [ ' n_predict ' ] = int ( data [ " nPredict " ] )
self . config [ ' seed ' ] = int ( data [ " seed " ] )
2023-04-14 08:48:14 +00:00
self . config [ ' model ' ] = str ( data [ " model " ] )
self . config [ ' voice ' ] = str ( data [ " voice " ] )
self . config [ ' language ' ] = str ( data [ " language " ] )
2023-04-08 16:00:02 +00:00
2023-04-12 20:36:03 +00:00
self . config [ ' temp ' ] = float ( data [ " temp " ] )
self . config [ ' top_k ' ] = int ( data [ " topK " ] )
self . config [ ' top_p ' ] = float ( data [ " topP " ] )
self . config [ ' repeat_penalty ' ] = float ( data [ " repeatPenalty " ] )
self . config [ ' repeat_last_n ' ] = int ( data [ " repeatLastN " ] )
2023-04-08 10:54:51 +00:00
2023-04-14 09:58:07 +00:00
save_config ( self . config , self . config_file_path )
2023-04-20 20:41:32 +00:00
print ( " ============================================== " )
2023-04-08 10:54:51 +00:00
print ( " Parameters changed to: " )
2023-04-20 20:41:32 +00:00
print ( f " \t Backend: { self . config [ ' backend ' ] } " )
2023-04-14 08:48:14 +00:00
print ( f " \t Model: { self . config [ ' model ' ] } " )
2023-04-20 20:20:18 +00:00
print ( f " \t Personality language: { self . config [ ' personality_language ' ] } " )
print ( f " \t Personality category: { self . config [ ' personality_category ' ] } " )
2023-04-14 08:48:14 +00:00
print ( f " \t Personality: { self . config [ ' personality ' ] } " )
print ( f " \t Language: { self . config [ ' language ' ] } " )
print ( f " \t Voice: { self . config [ ' voice ' ] } " )
2023-04-12 20:36:03 +00:00
print ( f " \t Temperature: { self . config [ ' temp ' ] } " )
print ( f " \t NPredict: { self . config [ ' n_predict ' ] } " )
print ( f " \t Seed: { self . config [ ' seed ' ] } " )
print ( f " \t op_k: { self . config [ ' top_k ' ] } " )
print ( f " \t op_p: { self . config [ ' top_p ' ] } " )
print ( f " \t repeat_penalty: { self . config [ ' repeat_penalty ' ] } " )
print ( f " \t repeat_last_n: { self . config [ ' repeat_last_n ' ] } " )
2023-04-20 20:41:32 +00:00
print ( " ============================================== " )
2023-04-20 20:43:29 +00:00
2023-04-07 21:22:17 +00:00
return jsonify ( { " status " : " ok " } )
2023-04-08 17:55:33 +00:00
2023-04-12 20:36:03 +00:00
def get_config ( self ) :
return jsonify ( self . config )
2023-04-08 17:55:33 +00:00
2023-04-13 10:31:48 +00:00
def main ( self ) :
return render_template ( " main.html " )
def settings ( self ) :
return render_template ( " settings.html " )
2023-04-11 20:56:15 +00:00
def help ( self ) :
return render_template ( " help.html " )
2023-04-11 23:34:50 +00:00
def training ( self ) :
return render_template ( " training.html " )
def extensions ( self ) :
return render_template ( " extensions.html " )
2023-04-07 16:58:42 +00:00
if __name__ == " __main__ " :
parser = argparse . ArgumentParser ( description = " Start the chatbot Flask app. " )
2023-04-13 15:24:52 +00:00
parser . add_argument (
" -c " , " --config " , type = str , default = " default " , help = " Sets the configuration file to be used. "
)
2023-04-13 15:55:15 +00:00
parser . add_argument (
" -p " , " --personality " , type = str , default = None , help = " Selects the personality to be using. "
)
2023-04-07 19:44:55 +00:00
parser . add_argument (
2023-04-13 13:27:50 +00:00
" -s " , " --seed " , type = int , default = None , help = " Force using a specific seed value. "
2023-04-07 19:44:55 +00:00
)
2023-04-07 16:58:42 +00:00
2023-04-07 19:44:55 +00:00
parser . add_argument (
2023-04-12 20:36:03 +00:00
" -m " , " --model " , type = str , default = None , help = " Force using a specific model. "
2023-04-07 19:44:55 +00:00
)
2023-04-07 16:58:42 +00:00
parser . add_argument (
2023-04-12 20:36:03 +00:00
" --temp " , type = float , default = None , help = " Temperature parameter for the model. "
2023-04-07 16:58:42 +00:00
)
parser . add_argument (
" --n_predict " ,
type = int ,
2023-04-12 20:36:03 +00:00
default = None ,
2023-04-07 16:58:42 +00:00
help = " Number of tokens to predict at each step. " ,
)
2023-04-16 19:33:34 +00:00
parser . add_argument (
" --n_threads " ,
type = int ,
default = None ,
help = " Number of threads to use. " ,
)
2023-04-07 16:58:42 +00:00
parser . add_argument (
2023-04-12 20:36:03 +00:00
" --top_k " , type = int , default = None , help = " Value for the top-k sampling. "
2023-04-07 16:58:42 +00:00
)
parser . add_argument (
2023-04-12 20:36:03 +00:00
" --top_p " , type = float , default = None , help = " Value for the top-p sampling. "
2023-04-07 16:58:42 +00:00
)
parser . add_argument (
2023-04-12 20:36:03 +00:00
" --repeat_penalty " , type = float , default = None , help = " Penalty for repeated tokens. "
2023-04-07 16:58:42 +00:00
)
parser . add_argument (
" --repeat_last_n " ,
type = int ,
2023-04-12 20:36:03 +00:00
default = None ,
2023-04-07 16:58:42 +00:00
help = " Number of previous tokens to consider for the repeat penalty. " ,
)
parser . add_argument (
" --ctx_size " ,
type = int ,
2023-04-12 20:36:03 +00:00
default = None , #2048,
2023-04-07 16:58:42 +00:00
help = " Size of the context window for the model. " ,
)
parser . add_argument (
" --debug " ,
dest = " debug " ,
action = " store_true " ,
help = " launch Flask server in debug mode " ,
)
parser . add_argument (
2023-04-13 10:31:48 +00:00
" --host " , type = str , default = None , help = " the hostname to listen on "
2023-04-07 16:58:42 +00:00
)
2023-04-12 20:36:03 +00:00
parser . add_argument ( " --port " , type = int , default = None , help = " the port to listen on " )
2023-04-07 16:58:42 +00:00
parser . add_argument (
2023-04-12 20:36:03 +00:00
" --db_path " , type = str , default = None , help = " Database path "
2023-04-07 16:58:42 +00:00
)
2023-04-06 19:12:49 +00:00
parser . set_defaults ( debug = False )
args = parser . parse_args ( )
2023-04-13 15:24:52 +00:00
2023-04-14 15:29:17 +00:00
# The default configuration must be kept unchanged as it is committed to the repository,
# so we have to make a copy that is not comitted
2023-04-14 15:11:40 +00:00
if args . config == " default " :
args . config = " local_default "
if not Path ( f " configs/local_default.yaml " ) . exists ( ) :
print ( " No local configuration file found. Building from scratch " )
shutil . copy ( f " configs/default.yaml " , f " configs/local_default.yaml " )
2023-04-13 15:24:52 +00:00
config_file_path = f " configs/ { args . config } .yaml "
2023-04-12 20:36:03 +00:00
config = load_config ( config_file_path )
# Override values in config with command-line arguments
for arg_name , arg_value in vars ( args ) . items ( ) :
if arg_value is not None :
config [ arg_name ] = arg_value
2023-04-06 19:12:49 +00:00
2023-04-30 20:40:19 +00:00
personality = AIPersonality ( f " personalities/ { config [ ' personality_language ' ] } / { config [ ' personality_category ' ] } / { config [ ' personality ' ] } " )
2023-04-13 15:55:15 +00:00
2023-04-24 20:02:50 +00:00
# executor = ThreadPoolExecutor(max_workers=1)
# app.config['executor'] = executor
2023-04-27 06:52:00 +00:00
bot = Gpt4AllWebUI ( app , socketio , config , personality , config_file_path )
2023-04-06 19:12:49 +00:00
2023-04-30 01:15:11 +00:00
# chong Define custom WebSocketHandler with error handling
class CustomWebSocketHandler ( WebSocketHandler ) :
def handle_error ( self , environ , start_response , e ) :
# Handle the error here
print ( " WebSocket error: " , e )
super ( ) . handle_error ( environ , start_response , e )
2023-04-30 20:40:19 +00:00
url = f ' http:// { config [ " host " ] } : { config [ " port " ] } '
print ( f " Please open your browser and go to { url } to view the ui " )
2023-04-30 01:15:11 +00:00
2023-05-01 02:17:03 +00:00
# chong -add socket server
app . config [ ' debug ' ] = config [ " debug " ]
2023-04-30 01:15:11 +00:00
2023-05-01 02:17:03 +00:00
if config [ " debug " ] :
print ( " debug mode:true " )
else :
print ( " debug mode:false " )
http_server = WSGIServer ( ( config [ " host " ] , config [ " port " ] ) , app , handler_class = WebSocketHandler )
2023-05-01 22:04:18 +00:00
http_server . serve_forever ( )
#if config["debug"]:
# app.run(debug=True, host=config["host"], port=config["port"])
#else:
# app.run(host=config["host"], port=config["port"])