mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-04-07 19:04:18 +00:00
V6.7 is here
This commit is contained in:
parent
f42382c679
commit
8376b05ceb
@ -20,7 +20,7 @@ from lollms.paths import LollmsPaths
|
||||
from lollms.helpers import ASCIIColors, trace_exception
|
||||
from lollms.app import LollmsApplication
|
||||
from lollms.utilities import File64BitsManager, PromptReshaper
|
||||
from safe_store import TextVectorizer, VectorizationMethod
|
||||
from safe_store import TextVectorizer, VectorizationMethod, VisualizationMethod
|
||||
import threading
|
||||
from tqdm import tqdm
|
||||
import traceback
|
||||
@ -115,6 +115,10 @@ class LoLLMsAPPI(LollmsApplication):
|
||||
def __init__(self, config:LOLLMSConfig, socketio, config_file_path:str, lollms_paths: LollmsPaths) -> None:
|
||||
|
||||
super().__init__("Lollms_webui",config, lollms_paths, callback=self.process_chunk)
|
||||
|
||||
|
||||
|
||||
|
||||
self.busy = False
|
||||
self.nb_received_tokens = 0
|
||||
|
||||
@ -123,7 +127,6 @@ class LoLLMsAPPI(LollmsApplication):
|
||||
self.cancel_gen = False
|
||||
|
||||
|
||||
self.discussion_store = None
|
||||
|
||||
# Keeping track of current discussion and message
|
||||
self._current_user_message_id = 0
|
||||
@ -144,6 +147,39 @@ class LoLLMsAPPI(LollmsApplication):
|
||||
self.db.add_missing_columns()
|
||||
ASCIIColors.success("ok")
|
||||
|
||||
|
||||
|
||||
# prepare vectorization
|
||||
if self.config.data_vectorization_activate and self.config.use_discussions_history:
|
||||
try:
|
||||
ASCIIColors.yellow("Loading vectorized discussions")
|
||||
folder = self.lollms_paths.personal_databases_path/"vectorized_dbs"
|
||||
folder.mkdir(parents=True, exist_ok=True)
|
||||
self.discussions_store = TextVectorizer(
|
||||
vectorization_method=VectorizationMethod.TFIDF_VECTORIZER,#=VectorizationMethod.BM25_VECTORIZER,
|
||||
database_path=folder/self.config.db_path,
|
||||
data_visualization_method=VisualizationMethod.PCA,#VisualizationMethod.PCA,
|
||||
save_db=True
|
||||
)
|
||||
|
||||
ASCIIColors.yellow("1- Exporting discussions")
|
||||
discussions = self.db.export_all_as_markdown_list_for_vectorization()
|
||||
ASCIIColors.yellow("2- Adding discussions to vectorizer")
|
||||
for (title,discussion) in discussions:
|
||||
if discussion!='':
|
||||
self.discussions_store.add_document(title, discussion, chunk_size=self.config.data_vectorization_chunk_size, overlap_size=self.config.data_vectorization_overlap_size, force_vectorize=False, add_as_a_bloc=False)
|
||||
ASCIIColors.yellow("3- Indexing database")
|
||||
self.discussions_store.index()
|
||||
ASCIIColors.yellow("3- Saving database")
|
||||
self.discussions_store.save_to_json()
|
||||
ASCIIColors.yellow("Ready")
|
||||
|
||||
except Exception as ex:
|
||||
trace_exception(ex)
|
||||
self.discussions_store = None
|
||||
else:
|
||||
self.discussions_store = None
|
||||
|
||||
# This is used to keep track of messages
|
||||
self.download_infos={}
|
||||
|
||||
@ -1161,21 +1197,11 @@ class LoLLMsAPPI(LollmsApplication):
|
||||
str_docs = ""
|
||||
|
||||
if self.config.use_discussions_history:
|
||||
if self.discussion_store is None:
|
||||
self.discussion_store = TextVectorizer(self.config.data_vectorization_method, # supported "model_embedding" or "tfidf_vectorizer"
|
||||
model=self.model, #needed in case of using model_embedding
|
||||
database_path=self.lollms_paths.personal_databases_path/"discussionsdb.json",
|
||||
save_db=self.config.data_vectorization_save_db,
|
||||
data_visualization_method=VectorizationMethod.PCA,
|
||||
database_dict=None)
|
||||
corpus = self.db.export_all_as_markdown()
|
||||
self.discussion_store.add_document("discussions", corpus, self.config.data_vectorization_chunk_size, self.config.data_vectorization_overlap_size )
|
||||
|
||||
pr = PromptReshaper("{{conditionning}}\n!@>document chunks:\n{{doc}}\n{{content}}")
|
||||
emb = self.discussion_store.embed_query(message.content)
|
||||
docs, sorted_similarities = self.discussion_store.recover_text(emb, top_k=self.config.data_vectorization_nb_chunks)
|
||||
for doc, infos in zip(docs, sorted_similarities):
|
||||
str_docs+=f"document chunk:\nchunk path: {infos[0]}\nchunk content:{doc}"
|
||||
if self.discussions_store is not None:
|
||||
pr = PromptReshaper("{{conditionning}}\n!@>document chunks:\n{{doc}}\n{{content}}")
|
||||
docs, sorted_similarities = self.discussions_store.recover_text(message.content, top_k=self.config.data_vectorization_nb_chunks)
|
||||
for doc, infos in zip(docs, sorted_similarities):
|
||||
str_docs+=f"discussion chunk:\ndiscussion title: {infos[0]}\nchunk content:{doc}"
|
||||
|
||||
|
||||
if len(self.personality.files)>0 and self.personality.vectorizer:
|
||||
|
19
api/db.py
19
api/db.py
@ -249,6 +249,25 @@ class DiscussionsDB:
|
||||
)
|
||||
discussions.append(discussion)
|
||||
return discussions
|
||||
|
||||
def export_all_as_markdown_list_for_vectorization(self):
|
||||
data = self.export_all_discussions_to_json()
|
||||
# Initialize an empty result string
|
||||
discussions = []
|
||||
# Iterate through discussions in the JSON data
|
||||
for discussion in data:
|
||||
# Extract the title
|
||||
title = discussion['title']
|
||||
messages = ""
|
||||
# Iterate through messages in the discussion
|
||||
for message in discussion['messages']:
|
||||
sender = message['sender']
|
||||
content = message['content']
|
||||
# Append the sender and content in a Markdown format
|
||||
messages += f'{sender}: {content}\n'
|
||||
discussions.append([title, messages])
|
||||
return discussions
|
||||
|
||||
def export_all_as_markdown(self):
|
||||
data = self.export_all_discussions_to_json()
|
||||
|
||||
|
76
app.py
76
app.py
@ -14,7 +14,7 @@ __github__ = "https://github.com/ParisNeo/lollms-webui"
|
||||
__copyright__ = "Copyright 2023, "
|
||||
__license__ = "Apache 2.0"
|
||||
|
||||
__version__ ="6.7Beta1"
|
||||
__version__ ="6.7"
|
||||
|
||||
main_repo = "https://github.com/ParisNeo/lollms-webui.git"
|
||||
import os
|
||||
@ -89,6 +89,7 @@ try:
|
||||
import shutil
|
||||
import socket
|
||||
from api.db import DiscussionsDB, Discussion
|
||||
from safe_store import TextVectorizer, VectorizationMethod, VisualizationMethod
|
||||
|
||||
except Exception as ex:
|
||||
trace_exception(ex)
|
||||
@ -302,9 +303,6 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
self.add_endpoint(
|
||||
"/list_bindings", "list_bindings", self.list_bindings, methods=["GET"]
|
||||
)
|
||||
self.add_endpoint(
|
||||
"/list_extensions", "list_extensions", self.list_extensions, methods=["GET"]
|
||||
)
|
||||
|
||||
self.add_endpoint(
|
||||
"/list_models", "list_models", self.list_models, methods=["GET"]
|
||||
@ -345,6 +343,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
self.add_endpoint("/user_infos/<path:filename>", "serve_user_infos", self.serve_user_infos, methods=["GET"])
|
||||
|
||||
self.add_endpoint("/images/<path:filename>", "serve_images", self.serve_images, methods=["GET"])
|
||||
self.add_endpoint("/extensions/<path:filename>", "serve_extensions", self.serve_extensions, methods=["GET"])
|
||||
self.add_endpoint("/bindings/<path:filename>", "serve_bindings", self.serve_bindings, methods=["GET"])
|
||||
self.add_endpoint("/personalities/<path:filename>", "serve_personalities", self.serve_personalities, methods=["GET"])
|
||||
self.add_endpoint("/outputs/<path:filename>", "serve_outputs", self.serve_outputs, methods=["GET"])
|
||||
@ -887,8 +886,31 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
self.rebuild_personalities()
|
||||
if self.config.auto_save:
|
||||
self.config.save_config()
|
||||
|
||||
if self.config.data_vectorization_activate and self.config.use_discussions_history:
|
||||
ASCIIColors.yellow("0- Detected discussion vectorization request")
|
||||
folder = self.lollms_paths.personal_databases_path/"vectorized_dbs"
|
||||
folder.mkdir(parents=True, exist_ok=True)
|
||||
self.discussions_store = TextVectorizer(
|
||||
vectorization_method=VectorizationMethod.TFIDF_VECTORIZER,#=VectorizationMethod.BM25_VECTORIZER,
|
||||
database_path=folder/self.config.db_path,
|
||||
data_visualization_method=VisualizationMethod.PCA,#VisualizationMethod.PCA,
|
||||
save_db=True
|
||||
)
|
||||
ASCIIColors.yellow("1- Exporting discussions")
|
||||
discussions = self.db.export_all_as_markdown_list_for_vectorization()
|
||||
ASCIIColors.yellow("2- Adding discussions to vectorizer")
|
||||
for (title,discussion) in discussions:
|
||||
if discussion!='':
|
||||
self.discussions_store.add_document(title, discussion, chunk_size=self.config.data_vectorization_chunk_size, overlap_size=self.config.data_vectorization_overlap_size, force_vectorize=False, add_as_a_bloc=False)
|
||||
ASCIIColors.yellow("3- Indexing database")
|
||||
self.discussions_store.index()
|
||||
ASCIIColors.yellow("3- Saving database")
|
||||
self.discussions_store.save_to_json()
|
||||
ASCIIColors.yellow("Ready")
|
||||
return jsonify({"status":True})
|
||||
except Exception as ex:
|
||||
except Exception as ex:
|
||||
trace_exception(ex)
|
||||
return jsonify({"status":False,"error":str(ex)})
|
||||
|
||||
|
||||
@ -1160,6 +1182,26 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
|
||||
if self.config.auto_save:
|
||||
self.config.save_config()
|
||||
|
||||
if self.config.data_vectorization_activate and self.config.use_discussions_history:
|
||||
ASCIIColors.yellow("0- Detected discussion vectorization request")
|
||||
folder = self.lollms_paths.personal_databases_path/"vectorized_dbs"
|
||||
folder.mkdir(parents=True, exist_ok=True)
|
||||
self.discussions_store = TextVectorizer(
|
||||
vectorization_method=VectorizationMethod.TFIDF_VECTORIZER,#=VectorizationMethod.BM25_VECTORIZER,
|
||||
database_path=folder/self.config.db_path,
|
||||
data_visualization_method=VisualizationMethod.PCA,#VisualizationMethod.PCA,
|
||||
save_db=True
|
||||
)
|
||||
ASCIIColors.yellow("1- Exporting discussions")
|
||||
discussions = self.db.export_all_as_markdown_list_for_vectorization()
|
||||
ASCIIColors.yellow("2- Adding discussions to vectorizer")
|
||||
for (title,discussion) in discussions:
|
||||
self.discussions_store.add_document(title, discussion, chunk_size=self.config.data_vectorization_chunk_size, overlap_size=self.config.data_vectorization_overlap_size, force_vectorize=False, add_as_a_bloc=False)
|
||||
ASCIIColors.yellow("3- Indexing database")
|
||||
self.discussions_store.index()
|
||||
ASCIIColors.yellow("Ready")
|
||||
|
||||
return jsonify({"status":True})
|
||||
|
||||
|
||||
@ -1213,6 +1255,14 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
|
||||
fn = filename.split("/")[-1]
|
||||
return send_from_directory(path, fn)
|
||||
|
||||
def serve_extensions(self, filename):
|
||||
path = str(self.lollms_paths.extensions_zoo_path/("/".join(filename.split("/")[:-1])))
|
||||
|
||||
fn = filename.split("/")[-1]
|
||||
return send_from_directory(path, fn)
|
||||
|
||||
|
||||
|
||||
def serve_bindings(self, filename):
|
||||
path = str(self.lollms_paths.bindings_zoo_path/("/".join(filename.split("/")[:-1])))
|
||||
@ -1398,15 +1448,17 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
try:
|
||||
ASCIIColors.info("Unmounting binding and model")
|
||||
self.binding = None
|
||||
self.model = None
|
||||
for per in self.mounted_personalities:
|
||||
per.model = None
|
||||
gc.collect()
|
||||
ASCIIColors.info("Reinstalling binding")
|
||||
old_bn = self.config.binding_name
|
||||
self.config.binding_name = data['name']
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths, InstallOption.FORCE_INSTALL)
|
||||
ASCIIColors.success("Binding reinstalled successfully")
|
||||
|
||||
ASCIIColors.info("Please select a model")
|
||||
self.config.binding_name = old_bn
|
||||
self.binding = BindingBuilder().build_binding(self.config, self.lollms_paths)
|
||||
self.model = self.binding.build_model()
|
||||
for per in self.mounted_personalities:
|
||||
per.model = self.model
|
||||
return jsonify({"status": True})
|
||||
except Exception as ex:
|
||||
ASCIIColors.error(f"Couldn't build binding: [{ex}]")
|
||||
@ -1856,9 +1908,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
||||
else:
|
||||
pth = str(config_file).replace('\\','/')
|
||||
ASCIIColors.error(f"nok : Extension not found @ {pth}")
|
||||
|
||||
ASCIIColors.yellow(f"Available personalities: {[p.name for p in self.mounted_personalities]}")
|
||||
return jsonify({"status": False, "error":f"Personality not found @ {pth}"})
|
||||
return jsonify({"status": False, "error":f"Extension not found @ {pth}"})
|
||||
|
||||
|
||||
|
||||
|
8
web/dist/assets/index-1e952553.css
vendored
Normal file
8
web/dist/assets/index-1e952553.css
vendored
Normal file
File diff suppressed because one or more lines are too long
209
web/dist/assets/index-97b789f4.js
vendored
209
web/dist/assets/index-97b789f4.js
vendored
File diff suppressed because one or more lines are too long
213
web/dist/assets/index-b30b467a.js
vendored
Normal file
213
web/dist/assets/index-b30b467a.js
vendored
Normal file
File diff suppressed because one or more lines are too long
8
web/dist/assets/index-da85d9b9.css
vendored
8
web/dist/assets/index-da85d9b9.css
vendored
File diff suppressed because one or more lines are too long
@ -10,4 +10,4 @@ pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5p
|
||||
Updated for @stackoverflow/stacks v0.64.0
|
||||
Code Blocks: /blob/v0.64.0/lib/css/components/_stacks-code-blocks.less
|
||||
Colors: /blob/v0.64.0/lib/css/exports/_stacks-constants-colors.less
|
||||
*/.hljs{color:#fff;background:#1c1b1b}.hljs-subst{color:#fff}.hljs-comment{color:#999}.hljs-attr,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-selector-tag{color:#88aece}.hljs-attribute{color:#c59bc1}.hljs-name,.hljs-number,.hljs-quote,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#f08d49}.hljs-selector-class{color:#88aece}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#b5bd68}.hljs-meta,.hljs-selector-pseudo{color:#88aece}.hljs-built_in,.hljs-literal,.hljs-title{color:#f08d49}.hljs-bullet,.hljs-code{color:#ccc}.hljs-meta .hljs-string{color:#b5bd68}.hljs-deletion{color:#de7176}.hljs-addition{color:#76c490}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
||||
*/.hljs{color:#fff;background:#1c1b1b}.hljs-subst{color:#fff}.hljs-comment{color:#999}.hljs-keyword,.hljs-selector-tag,.hljs-meta .hljs-keyword,.hljs-doctag,.hljs-section,.hljs-attr{color:#88aece}.hljs-attribute{color:#c59bc1}.hljs-name,.hljs-type,.hljs-number,.hljs-selector-id,.hljs-quote,.hljs-template-tag{color:#f08d49}.hljs-selector-class{color:#88aece}.hljs-string,.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr{color:#b5bd68}.hljs-meta,.hljs-selector-pseudo{color:#88aece}.hljs-built_in,.hljs-title,.hljs-literal{color:#f08d49}.hljs-bullet,.hljs-code{color:#ccc}.hljs-meta .hljs-string{color:#b5bd68}.hljs-deletion{color:#de7176}.hljs-addition{color:#76c490}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
@ -10,4 +10,4 @@ pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5p
|
||||
Updated for @stackoverflow/stacks v0.64.0
|
||||
Code Blocks: /blob/v0.64.0/lib/css/components/_stacks-code-blocks.less
|
||||
Colors: /blob/v0.64.0/lib/css/exports/_stacks-constants-colors.less
|
||||
*/.hljs{color:#2f3337;background:#f6f6f6}.hljs-subst{color:#2f3337}.hljs-comment{color:#656e77}.hljs-attr,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-selector-tag{color:#015692}.hljs-attribute{color:#803378}.hljs-name,.hljs-number,.hljs-quote,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#b75501}.hljs-selector-class{color:#015692}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#54790d}.hljs-meta,.hljs-selector-pseudo{color:#015692}.hljs-built_in,.hljs-literal,.hljs-title{color:#b75501}.hljs-bullet,.hljs-code{color:#535a60}.hljs-meta .hljs-string{color:#54790d}.hljs-deletion{color:#c02d2e}.hljs-addition{color:#2f6f44}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
||||
*/.hljs{color:#2f3337;background:#f6f6f6}.hljs-subst{color:#2f3337}.hljs-comment{color:#656e77}.hljs-keyword,.hljs-selector-tag,.hljs-meta .hljs-keyword,.hljs-doctag,.hljs-section,.hljs-attr{color:#015692}.hljs-attribute{color:#803378}.hljs-name,.hljs-type,.hljs-number,.hljs-selector-id,.hljs-quote,.hljs-template-tag{color:#b75501}.hljs-selector-class{color:#015692}.hljs-string,.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr{color:#54790d}.hljs-meta,.hljs-selector-pseudo{color:#015692}.hljs-built_in,.hljs-title,.hljs-literal{color:#b75501}.hljs-bullet,.hljs-code{color:#535a60}.hljs-meta .hljs-string{color:#54790d}.hljs-deletion{color:#c02d2e}.hljs-addition{color:#2f6f44}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
@ -1,8 +0,0 @@
|
||||
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
|
||||
Theme: Tokyo-night-Dark
|
||||
origin: https://github.com/enkia/tokyo-night-vscode-theme
|
||||
Description: Original highlight.js style
|
||||
Author: (c) Henri Vandersleyen <hvandersleyen@gmail.com>
|
||||
License: see project LICENSE
|
||||
Touched: 2022
|
||||
*/.hljs-comment,.hljs-meta{color:#565f89}.hljs-deletion,.hljs-doctag,.hljs-regexp,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-tag,.hljs-template-tag,.hljs-variable.language_{color:#f7768e}.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-template-variable,.hljs-type,.hljs-variable{color:#ff9e64}.hljs-attribute,.hljs-built_in{color:#e0af68}.hljs-keyword,.hljs-property,.hljs-subst,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#7dcfff}.hljs-selector-tag{color:#73daca}.hljs-addition,.hljs-bullet,.hljs-quote,.hljs-string,.hljs-symbol{color:#9ece6a}.hljs-code,.hljs-formula,.hljs-section{color:#7aa2f7}.hljs-attr,.hljs-char.escape_,.hljs-keyword,.hljs-name,.hljs-operator{color:#bb9af7}.hljs-punctuation{color:#c0caf5}.hljs{background:#1a1b26;color:#9aa5ce}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
8
web/dist/assets/tokyo-night-dark-f9656fc4.css
vendored
Normal file
8
web/dist/assets/tokyo-night-dark-f9656fc4.css
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
|
||||
Theme: Tokyo-night-Dark
|
||||
origin: https://github.com/enkia/tokyo-night-vscode-theme
|
||||
Description: Original highlight.js style
|
||||
Author: (c) Henri Vandersleyen <hvandersleyen@gmail.com>
|
||||
License: see project LICENSE
|
||||
Touched: 2022
|
||||
*/.hljs-meta,.hljs-comment{color:#565f89}.hljs-tag,.hljs-doctag,.hljs-selector-id,.hljs-selector-class,.hljs-regexp,.hljs-template-tag,.hljs-selector-pseudo,.hljs-selector-attr,.hljs-variable.language_,.hljs-deletion{color:#f7768e}.hljs-variable,.hljs-template-variable,.hljs-number,.hljs-literal,.hljs-type,.hljs-params,.hljs-link{color:#ff9e64}.hljs-built_in,.hljs-attribute{color:#e0af68}.hljs-selector-tag{color:#2ac3de}.hljs-keyword,.hljs-title.function_,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-subst,.hljs-property{color:#7dcfff}.hljs-selector-tag{color:#73daca}.hljs-quote,.hljs-string,.hljs-symbol,.hljs-bullet,.hljs-addition{color:#9ece6a}.hljs-code,.hljs-formula,.hljs-section{color:#7aa2f7}.hljs-name,.hljs-keyword,.hljs-operator,.hljs-char.escape_,.hljs-attr{color:#bb9af7}.hljs-punctuation{color:#c0caf5}.hljs{background:#1a1b26;color:#9aa5ce}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}
|
4
web/dist/index.html
vendored
4
web/dist/index.html
vendored
@ -6,8 +6,8 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LoLLMS WebUI - Welcome</title>
|
||||
<script type="module" crossorigin src="/assets/index-97b789f4.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-da85d9b9.css">
|
||||
<script type="module" crossorigin src="/assets/index-b30b467a.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-1e952553.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
1038
web/package-lock.json
generated
1038
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
||||
"flowbite": "^1.6.5",
|
||||
"flowbite-vue": "^0.0.10",
|
||||
"highlight.js": "^11.8.0",
|
||||
"markdown-it": "^13.0.1",
|
||||
"markdown-it": "^13.0.2",
|
||||
"markdown-it-anchor": "^8.6.7",
|
||||
"markdown-it-attrs": "^4.1.6",
|
||||
"markdown-it-emoji": "^2.0.2",
|
||||
|
@ -56,11 +56,24 @@ h4 {
|
||||
}
|
||||
|
||||
/* Include any additional styles you need */
|
||||
p {
|
||||
font-size: 16px;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: disc;
|
||||
margin-left: 5px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: disc;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
ol {
|
||||
list-style-type: decimal;
|
||||
margin-left: 20px;
|
||||
}
|
@ -76,12 +76,16 @@
|
||||
title="Copy message to clipboard" @click.stop="copyContentToClipboard()">
|
||||
<i data-feather="copy"></i>
|
||||
</div>
|
||||
<div v-if="message.sender!=this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Resend message"
|
||||
@click.stop="resendMessage()" :class="{ 'disabled': editMsgMode }">
|
||||
<div v-if="!editMsgMode && message.sender!=this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2"
|
||||
title="Resend message"
|
||||
@click.stop="resendMessage()"
|
||||
:class="{ 'text-5xl': editMsgMode }">
|
||||
<i data-feather="refresh-cw"></i>
|
||||
</div>
|
||||
<div v-if="message.sender==this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2" title="Resend message"
|
||||
@click.stop="continueMessage()" :class="{ 'disabled': editMsgMode }">
|
||||
<div v-if="!editMsgMode && message.sender==this.$store.state.mountedPers.name" class="text-lg hover:text-secondary duration-75 active:scale-90 p-2"
|
||||
title="Resend message"
|
||||
@click.stop="continueMessage()"
|
||||
>
|
||||
<i data-feather="fast-forward"></i>
|
||||
</div>
|
||||
<!-- DELETE CONFIRMATION -->
|
||||
@ -96,7 +100,7 @@
|
||||
</button>
|
||||
|
||||
</div>
|
||||
<div v-if="!deleteMsgMode" class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2"
|
||||
<div v-if="!editMsgMode && !deleteMsgMode" class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2"
|
||||
title="Remove message" @click="deleteMsgMode = true">
|
||||
<i data-feather="trash"></i>
|
||||
</div>
|
||||
@ -142,11 +146,17 @@
|
||||
|
||||
<MarkdownRenderer ref="mdRender" v-if="!editMsgMode" :markdown-text="message.content">
|
||||
</MarkdownRenderer>
|
||||
<textarea v-if="editMsgMode" ref="mdTextarea" :rows="4"
|
||||
class="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
<div >
|
||||
<textarea v-if="editMsgMode" ref="mdTextarea" @keydown.tab.prevent="insertTab"
|
||||
class="block p-2.5 w-full text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 overflow-y-scroll flex flex-col shadow-lg p-10 pt-0 overflow-y-scroll w-full dark:bg-bg-dark scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary"
|
||||
:rows="4"
|
||||
:style="{ minHeight: mdRenderHeight + `px` }" placeholder="Enter message here..."
|
||||
v-model="message.content"></textarea>
|
||||
<div v-if="message.metadata !== null">
|
||||
v-model="message.content">
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-if="message.metadata !== null">
|
||||
<div v-for="(metadata, index) in message.metadata" :key="'json-' + message.id + '-' + index" class="json font-bold">
|
||||
<JsonViewer :jsonFormText="metadata.title" :jsonData="metadata.content" />
|
||||
</div>
|
||||
@ -202,7 +212,6 @@ import RenderHTMLJS from './RenderHTMLJS.vue';
|
||||
import JsonViewer from "./JsonViewer.vue";
|
||||
import Step from './Step.vue';
|
||||
import DynamicUIRenderer from "./DynamicUIRenderer.vue"
|
||||
|
||||
export default {
|
||||
// eslint-disable-next-line vue/multi-word-component-names
|
||||
name: 'Message',
|
||||
@ -212,7 +221,7 @@ export default {
|
||||
Step,
|
||||
RenderHTMLJS,
|
||||
JsonViewer,
|
||||
DynamicUIRenderer
|
||||
DynamicUIRenderer,
|
||||
},
|
||||
props: {
|
||||
message: Object,
|
||||
@ -254,7 +263,25 @@ export default {
|
||||
})
|
||||
|
||||
}, methods: {
|
||||
|
||||
insertTab(event) {
|
||||
const textarea = event.target;
|
||||
const start = textarea.selectionStart;
|
||||
const end = textarea.selectionEnd;
|
||||
|
||||
const textBefore = textarea.value.substring(0, start);
|
||||
const textAfter = textarea.value.substring(end);
|
||||
|
||||
// Insert a tab character (or spaces if you prefer) at the cursor position
|
||||
const newText = textBefore + ' ' + textAfter;
|
||||
|
||||
// Update the textarea content and cursor position
|
||||
this.message.content = newText;
|
||||
this.$nextTick(() => {
|
||||
textarea.selectionStart = textarea.selectionEnd = start + 4;
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
},
|
||||
onVoicesChanged() {
|
||||
// This event will be triggered when the voices are loaded
|
||||
this.voices = this.speechSynthesis.getVoices();
|
||||
|
@ -736,6 +736,11 @@ export default {
|
||||
}
|
||||
},
|
||||
async selectDiscussion(item) {
|
||||
if(this.isGenerating){
|
||||
this.$refs.toast.showToast("You are currently generating a text. Please wait for text generation to finish or stop it before trying to select another discussion", 4, false)
|
||||
return;
|
||||
}
|
||||
|
||||
if (item) {
|
||||
// When discussion is selected it loads the discussion array
|
||||
if (this.currentDiscussion===undefined) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
|
||||
<div class="container mx-auto p-4 bg-bg-light-tone dark:bg-bg-dark-tone shadow-lg overflow-y-auto no-scrollbar p-2 pb-0 grid lg:grid-cols-3 md:grid-cols-2 gap-4">
|
||||
<div class="container flex-row mx-auto p-4 bg-bg-light-tone dark:bg-bg-dark-tone shadow-lg overflow-y-auto no-scrollbar p-2 pb-0 grid lg:grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<Card :disableHoverAnimation="true" :disableFocus="true">
|
||||
<h2 class="text-2xl font-bold mb-2">About Lord of large Language Models</h2>
|
||||
<p class="mb-4"> Lollms version {{ version }}</p>
|
||||
|
@ -42,12 +42,13 @@
|
||||
</div>
|
||||
<div class="flex-grow m-2 p-2 border border-blue-300 rounded-md border-2 border-blue-300 m-2 p-4" :class="{ 'border-red-500': generating }">
|
||||
<div v-if="tab_id === 'source'">
|
||||
<textarea
|
||||
@click="text_element_clicked"
|
||||
@keyup="text_element_changed"
|
||||
v-model="text"
|
||||
ref="text_element"
|
||||
class="bg-white dark:bg-black m-0 border-2 rounded-md shadow-sm w-full mt-4 h-64 p-2 rounded shadow-lg overflow-y-scroll w-full dark:bg-bg-dark scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary" type="text"></textarea>
|
||||
<textarea ref="mdTextarea" @keydown.tab.prevent="insertTab"
|
||||
class="block min-h-500 p-2.5 w-full text-gray-900 bg-gray-50 rounded-lg border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500 overflow-y-scroll flex flex-col shadow-lg p-10 pt-0 overflow-y-scroll dark:bg-bg-dark scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary"
|
||||
:rows="4"
|
||||
:style="{ minHeight: mdRenderHeight + `px` }" placeholder="Enter message here..."
|
||||
v-model="text">
|
||||
</textarea>
|
||||
|
||||
<span>Cursor position {{ cursorPosition }}</span>
|
||||
</div>
|
||||
<div v-if="tab_id === 'render'">
|
||||
@ -427,6 +428,25 @@ export default {
|
||||
},
|
||||
},
|
||||
methods:{
|
||||
insertTab(event) {
|
||||
const textarea = event.target;
|
||||
const start = textarea.selectionStart;
|
||||
const end = textarea.selectionEnd;
|
||||
|
||||
const textBefore = textarea.value.substring(0, start);
|
||||
const textAfter = textarea.value.substring(end);
|
||||
|
||||
// Insert a tab character (or spaces if you prefer) at the cursor position
|
||||
const newText = textBefore + ' ' + textAfter;
|
||||
|
||||
// Update the textarea content and cursor position
|
||||
this.text = newText;
|
||||
this.$nextTick(() => {
|
||||
textarea.selectionStart = textarea.selectionEnd = start + 4;
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
},
|
||||
text_element_changed(){
|
||||
console.log("text_element_changed")
|
||||
this.cursorPosition = this.$refs.text_element.selectionStart;
|
||||
|
Loading…
x
Reference in New Issue
Block a user