Removed V1 definetely

This commit is contained in:
Saifeddine ALOUI 2023-10-20 17:02:56 +02:00
parent 0046a804fb
commit 7aa3cc90b4
53 changed files with 218 additions and 271093 deletions

2
.gitmodules vendored
View File

@ -14,7 +14,7 @@
path = zoos/models_zoo path = zoos/models_zoo
url = https://github.com/ParisNeo/models_zoo.git url = https://github.com/ParisNeo/models_zoo.git
branch = main branch = main
[submodule "lollms"] [submodule "lollms_core"]
path = lollms_core path = lollms_core
url = https://github.com/ParisNeo/lollms.git url = https://github.com/ParisNeo/lollms.git
branch = main branch = main

@ -1 +1 @@
Subproject commit 6f583fe3164d389fbcc91617e5b58b21cb9c33a6 Subproject commit ec5b4bd018067af50a0cb2e6c06d3dbfbad88de8

View File

@ -1,62 +0,0 @@
/* Wait animation */
.lds-facebook {
display: inline-block;
position: relative;
width: 40px;
height: 40px;
}
.lds-facebook div {
display: inline-block;
position: absolute;
left: 8px;
width: 8px;
background: #fff;
animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
}
.lds-facebook div:nth-child(1) {
left: 4px;
animation-delay: -0.24s;
}
.lds-facebook div:nth-child(2) {
left: 16px;
animation-delay: -0.12s;
}
.lds-facebook div:nth-child(3) {
left: 28px;
animation-delay: 0;
}
@keyframes lds-facebook {
0% {
top: 8px;
height: 34px;
}
50%, 100% {
top: 12px;
height: 18px;
}
}
.activeDiscussion {
background-color: #16a34a; /*Equivalent to bg-green-600*/
}
:root {
--color-primary-light: #ffffff;
--color-secondary-light: #f2f2f2;
--color-primary-dark: #1a1a1a;
--color-secondary-dark: #333333;
}
/* Default light mode styles */
.text-primary {
color: var(--color-primary-light);
}
/* Dark mode styles */
@media (prefers-color-scheme: dark) {
.mode-dark .text-primary {
color: var(--color-primary-dark);
}
}

View File

@ -1,42 +0,0 @@
/* Style for the help page */
.container {
max-width: 960px;
margin: 0 auto;
padding: 0 1rem;
}
.section-title {
margin-top: 2rem;
margin-bottom: 1.5rem;
}
.section-title h2 {
font-size: 2.5rem;
font-weight: bold;
text-transform: uppercase;
letter-spacing: 0.1em;
}
.section-title p {
font-size: 1.125rem;
font-weight: 300;
}
.list-disc,
.list-decimal {
margin-left: 2rem;
}
.list-inside {
margin-left: 1.5rem;
}
.faq dt {
font-weight: bold;
margin-top: 1.5rem;
}
.faq dd {
margin-left: 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,805 +0,0 @@
/*
! tailwindcss v3.1.4 | MIT License | https://tailwindcss.com
*//*
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
*/
*,
::before,
::after {
box-sizing: border-box; /* 1 */
border-width: 0; /* 2 */
border-style: solid; /* 2 */
border-color: #e5e7eb; /* 2 */
}
::before,
::after {
--tw-content: '';
}
/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
3. Use a more readable tab size.
4. Use the user's configured `sans` font-family by default.
*/
html {
line-height: 1.5; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-moz-tab-size: 4; /* 3 */
-o-tab-size: 4;
tab-size: 4; /* 3 */
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
}
/*
1. Remove the margin in all browsers.
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
*/
body {
margin: 0; /* 1 */
line-height: inherit; /* 2 */
}
/*
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
3. Ensure horizontal rules are visible by default.
*/
hr {
height: 0; /* 1 */
color: inherit; /* 2 */
border-top-width: 1px; /* 3 */
}
/*
Add the correct text decoration in Chrome, Edge, and Safari.
*/
abbr:where([title]) {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}
/*
Remove the default font size and weight for headings.
*/
h1 {
font-size: 36px;
font-weight: bold;
}
h2,
h3,
h4,
h5,
h6 {
font-size: inherit;
font-weight: inherit;
}
/*
Reset links to optimize for opt-in styling instead of opt-out.
*/
a {
color: inherit;
text-decoration: inherit;
}
/*
Add the correct font weight in Edge and Safari.
*/
b,
strong {
font-weight: bolder;
}
/*
1. Use the user's configured `mono` font family by default.
2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp,
pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */
font-size: 1em; /* 2 */
}
/*
Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/*
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/*
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
3. Remove gaps between table borders by default.
*/
table {
text-indent: 0; /* 1 */
border-color: inherit; /* 2 */
border-collapse: collapse; /* 3 */
}
/*
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
3. Remove default padding in all browsers.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
font-weight: inherit; /* 1 */
line-height: inherit; /* 1 */
color: inherit; /* 1 */
margin: 0; /* 2 */
padding: 0; /* 3 */
}
/*
Remove the inheritance of text transform in Edge and Firefox.
*/
button,
select {
text-transform: none;
}
/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Remove default button styles.
*/
button,
[type='button'],
[type='reset'],
[type='submit'] {
-webkit-appearance: button; /* 1 */
background-color: transparent; /* 2 */
background-image: none; /* 2 */
}
/*
Use the modern Firefox focus style for all focusable elements.
*/
:-moz-focusring {
outline: auto;
}
/*
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
*/
:-moz-ui-invalid {
box-shadow: none;
}
/*
Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
vertical-align: baseline;
}
/*
Correct the cursor style of increment and decrement buttons in Safari.
*/
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
height: auto;
}
/*
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/
[type='search'] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/*
Remove the inner padding in Chrome and Safari on macOS.
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/*
Add the correct display in Chrome and Safari.
*/
summary {
display: list-item;
}
/*
Removes the default spacing and border for appropriate elements.
*/
blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
margin: 0;
}
fieldset {
margin: 0;
padding: 0;
}
legend {
padding: 0;
}
ol,
ul,
menu {
list-style: none;
margin: 0;
padding: 0;
}
/*
Prevent resizing textareas horizontally by default.
*/
textarea {
resize: vertical;
}
/*
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
2. Set the default placeholder color to the user's configured gray 400 color.
*/
input::-moz-placeholder, textarea::-moz-placeholder {
opacity: 1; /* 1 */
color: #9ca3af; /* 2 */
}
input:-ms-input-placeholder, textarea:-ms-input-placeholder {
opacity: 1; /* 1 */
color: #9ca3af; /* 2 */
}
input::placeholder,
textarea::placeholder {
opacity: 1; /* 1 */
color: #9ca3af; /* 2 */
}
/*
Set the default cursor for buttons.
*/
button,
[role="button"] {
cursor: pointer;
}
/*
Make sure disabled buttons don't get the pointer cursor.
*/
:disabled {
cursor: default;
}
/*
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
This can trigger a poorly considered lint error in some tools but is included by design.
*/
img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
display: block; /* 1 */
vertical-align: middle; /* 2 */
}
/*
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
*/
img,
video {
max-width: 100%;
height: auto;
}
*, ::before, ::after {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
::-webkit-backdrop {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
::backdrop {
--tw-border-spacing-x: 0;
--tw-border-spacing-y: 0;
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
--tw-pan-x: ;
--tw-pan-y: ;
--tw-pinch-zoom: ;
--tw-scroll-snap-strictness: proximity;
--tw-ordinal: ;
--tw-slashed-zero: ;
--tw-numeric-figure: ;
--tw-numeric-spacing: ;
--tw-numeric-fraction: ;
--tw-ring-inset: ;
--tw-ring-offset-width: 0px;
--tw-ring-offset-color: #fff;
--tw-ring-color: rgb(59 130 246 / 0.5);
--tw-ring-offset-shadow: 0 0 #0000;
--tw-ring-shadow: 0 0 #0000;
--tw-shadow: 0 0 #0000;
--tw-shadow-colored: 0 0 #0000;
--tw-blur: ;
--tw-brightness: ;
--tw-contrast: ;
--tw-grayscale: ;
--tw-hue-rotate: ;
--tw-invert: ;
--tw-saturate: ;
--tw-sepia: ;
--tw-drop-shadow: ;
--tw-backdrop-blur: ;
--tw-backdrop-brightness: ;
--tw-backdrop-contrast: ;
--tw-backdrop-grayscale: ;
--tw-backdrop-hue-rotate: ;
--tw-backdrop-invert: ;
--tw-backdrop-opacity: ;
--tw-backdrop-saturate: ;
--tw-backdrop-sepia: ;
}
.mx-6 {
margin-left: 1.5rem;
margin-right: 1.5rem;
}
.my-4 {
margin-top: 1rem;
margin-bottom: 1rem;
}
.my-1 {
margin-top: 0.25rem;
margin-bottom: 0.25rem;
}
.mx-1 {
margin-left: 0.25rem;
margin-right: 0.25rem;
}
.flex {
display: flex;
}
.h-screen {
height: 100vh;
}
.h-20 {
height: 5rem;
}
.h-12 {
height: 3rem;
}
.h-full {
height: 100%;
}
.max-h-full {
max-height: 100%;
}
.w-screen {
width: 100vw;
}
.w-full {
width: 100%;
}
.w-12 {
width: 3rem;
}
.flex-col {
flex-direction: column;
}
.items-center {
align-items: center;
}
.justify-between {
justify-content: space-between;
}
.space-y-0 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0px * var(--tw-space-y-reverse));
}
.space-x-2 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0.5rem * var(--tw-space-x-reverse));
margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
}
.overflow-hidden {
overflow: hidden;
}
.overflow-y-auto {
overflow-y: auto;
}
.rounded-md {
border-radius: 0.375rem;
}
.border-b {
border-bottom-width: 1px;
}
.border-t {
border-top-width: 1px;
}
.border-accent {
border-color: var(--accent);
}
.bg-primary {
background-color: var(--primary);
}
.bg-tertiary {
background-color: var(--tertiary);
}
.bg-secondary {
background-color: var(--secondary);
}
.bg-accent {
background-color: var(--accent);
}
.p-4 {
padding: 1rem;
}
.p-2 {
padding: 0.5rem;
}
.px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.text-2xl {
font-size: 1.5rem;
line-height: 2rem;
}
.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}
.font-bold {
font-weight: 700;
}
.font-normal {
font-weight: 400;
}
.font-medium {
font-weight: 500;
}
.text-gray-400 {
--tw-text-opacity: 1;
color: rgb(156 163 175 / var(--tw-text-opacity));
}
.text-black {
--tw-text-opacity: 1;
color: rgb(0 0 0 / var(--tw-text-opacity));
}
.underline {
-webkit-text-decoration-line: underline;
text-decoration-line: underline;
}
.outline-none {
outline: 2px solid transparent;
outline-offset: 2px;
}
.drop-shadow-sm {
--tw-drop-shadow: drop-shadow(0 1px 1px rgb(0 0 0 / 0.05));
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.transition-colors {
transition-property: color, background-color, border-color, fill, stroke, -webkit-text-decoration-color;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.ease-in-out {
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
:root {
--primary: #1a1d21;
--secondary: #212529;
--teriary: #23282c;
--accent: #6691e7;
}
.hover\:bg-\[\#7ba0ea\]:hover {
--tw-bg-opacity: 1;
background-color: rgb(123 160 234 / var(--tw-bg-opacity));
}
.active\:bg-\[\#3d73e1\]:active {
--tw-bg-opacity: 1;
background-color: rgb(61 115 225 / var(--tw-bg-opacity));
}
@media (min-width: 640px) {
.sm\:space-x-reverse > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 1;
}
.sm\:border-b {
border-bottom-width: 1px;
}
}
@media (min-width: 768px) {
.md\:h-1\/2 {
height: 50%;
}
.md\:w-1\/3 {
width: 33.333333%;
}
.md\:flex-row {
flex-direction: row;
}
.md\:flex-col {
flex-direction: column;
}
.md\:border-r {
border-right-width: 1px;
}
.md\:border-b-0 {
border-bottom-width: 0px;
}
.md\:border-b {
border-bottom-width: 1px;
}
}
@media (min-width: 1024px) {
.lg\:w-1\/4 {
width: 25%;
}
}
@media (min-width: 1280px) {
.xl\:w-1\/5 {
width: 20%;
}
}
.collapsible-header {
cursor: pointer;
}
.collapsible-content {
display: none;
}
/* Wait animation */
.lds-facebook {
display: inline-block;
position: relative;
width: 40px;
height: 40px;
}
.lds-facebook div {
display: inline-block;
position: absolute;
left: 8px;
width: 8px;
background: #fff;
animation: lds-facebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
}
.lds-facebook div:nth-child(1) {
left: 4px;
animation-delay: -0.24s;
}
.lds-facebook div:nth-child(2) {
left: 16px;
animation-delay: -0.12s;
}
.lds-facebook div:nth-child(3) {
left: 28px;
animation-delay: 0;
}
@keyframes lds-facebook {
0% {
top: 8px;
height: 34px;
}
50%, 100% {
top: 12px;
height: 18px;
}
}
li {
text-shadow: #0000;
}
ul {
list-style-type: disc;
}
ol {
list-style-type: decimal;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#fff" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>

Before

Width:  |  Height:  |  Size: 281 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#currentColor" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-sun"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>

Before

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!-- Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M402.6 83.2l90.2 90.2c3.8 3.8 3.8 10 0 13.8L274.4 405.6l-92.8 10.3c-12.4 1.4-22.9-9.1-21.5-21.5l10.3-92.8L388.8 83.2c3.8-3.8 10-3.8 13.8 0zm162-22.9l-48.8-48.8c-15.2-15.2-39.9-15.2-55.2 0l-35.4 35.4c-3.8 3.8-3.8 10 0 13.8l90.2 90.2c3.8 3.8 10 3.8 13.8 0l35.4-35.4c15.2-15.3 15.2-40 0-55.2zM384 346.2V448H64V128h229.8c3.2 0 6.2-1.3 8.5-3.5l40-40c7.6-7.6 2.2-20.5-8.5-20.5H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V306.2c0-10.7-12.9-16-20.5-8.5l-40 40c-2.2 2.3-3.5 5.3-3.5 8.5z"/></svg>

Before

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,203 +0,0 @@
// Dirty fix for disabling speech synth for firefox browsers :()
if (!userAgent.match(/firefox|fxios/i)) {
isStarted = false;
isSpeaking = false;
const SpeechRecognition = window.SpeechRecognition || webkitSpeechRecognition;
const recognition = new SpeechRecognition();
const synth = window.speechSynthesis || webkitspeechSynthesis;
var voices = synth.getVoices();
function prepre_audio() {
recognition.continuous = true;
recognition.interimResults = true;
recognition.maxAlternatives = 10;
language_select = document.getElementById("language")
}
voices = [];
function populateVoicesList() {
voices = synth.getVoices();
voice_select = document.getElementById("voice")
voice_select.innerHTML = "";
for (let i = 0; i < voices.length; i++) {
if (
voices[i].lang.startsWith(
language_select.value.substring(0, 2)
)
) {
const option = document.createElement("option");
option.textContent = `${voices[i].name} (${voices[i].lang})`;
if (voices[i].default) {
option.textContent += " — DEFAULT";
}
option.setAttribute("data-lang", voices[i].lang);
option.setAttribute("data-name", voices[i].name);
voice_select.appendChild(option);
}
}
voice_select.addEventListener("change", function () {
});
}
// Audio code
function splitString(string, maxLength) {
const sentences = string.match(/[^.!?]+[.!?]/g);
const strings = [];
let currentString = "";
if (sentences) {
for (const sentence of sentences) {
if (currentString.length + sentence.length > maxLength) {
strings.push(currentString);
currentString = "";
}
currentString += `${sentence} `;
}
} else {
strings.push(string);
}
if (currentString) {
strings.push(currentString);
}
return strings;
}
function addListeners(button, utterThis) {
utterThis.onstart = (event) => {
isSpeaking = true;
button.style.backgroundColor = "red";
button.style.boxShadow = "2px 2px 0.5px #808080";
};
utterThis.onend = (event) => {
isSpeaking = false;
button.style.backgroundColor = "";
button.style.boxShadow = "";
};
}
function attachAudio_modules(div, container) {
if (container.getElementsByClassName("audio-out-button").length > 0) {
return;
}
const audio_out_button = document.createElement("button");
audio_out_button.title = "Listen to message";
audio_out_button.id = "audio-out-button";
audio_out_button.classList.add("audio_btn",'bg-gray-500', 'hover:bg-gray-700', 'text-white', 'font-bold', 'py-0', 'px-0', 'rounded-r', "w-10", "h-10");
audio_out_button.innerHTML = "🕪";
audio_out_button.classList.add("audio-out-button");
container.appendChild(audio_out_button);
function play_audio() {
console.log("Playing audio")
if (isSpeaking) {
audio_out_button.style.backgroundColor = "";
audio_out_button.style.boxShadow = "";
synth.cancel();
isSpeaking = false;
} else {
isSpeaking = true;
text = div.textContent;
const selectedOption =
voice_select.selectedOptions[0].getAttribute("data-name");
var selectedVoice = null;
for (let i = 0; i < voices.length; i++) {
if (voices[i].name === selectedOption) {
selectedVoice = voices[i];
}
}
if (selectedVoice && selectedVoice.voiceURI === "native") {
const utterThis = new SpeechSynthesisUtterance(text);
utterThis.voice = selectedVoice;
addListeners(audio_out_button, utterThis);
synth.speak(utterThis);
} else {
console.log("Not native")
texts = splitString(text, 200);
console.log(`Text to say ${texts}`)
texts.forEach((text) => {
const utterThis = new SpeechSynthesisUtterance(text);
utterThis.voice = selectedVoice;
addListeners(audio_out_button, utterThis);
synth.speak(utterThis);
});
}
}
}
audio_out_button.addEventListener("click", () => {
play_audio();
});
// TODO : activate using configuration file
//if (global["auto_audio"]) {
// play_audio();
//}
}
function add_audio_in_ui() {
const input = document.getElementById("user-input");
// const wrapper = document.createElement("div");
// wrapper.classList.add("flex", "items-center");
var btn = document.querySelectorAll("#audio_in_tool");
var found = false;
// Iterate through the children
for (var i = 0; i < btn.length; i++) {
var child = btn[i];
// Check if the wrapper element contains the current child element
if (input.parentNode.parentNode.contains(child)) {
found = true;
}
}
if (!found) {
const audio_in_button = document.createElement("button");
audio_in_button.title = "Type with your voice";
audio_in_button.id = "audio_in_tool";
audio_in_button.classList.add("audio_btn");
audio_in_button.innerHTML = "🎤";
input.parentNode.parentNode.insertBefore(
audio_in_button,
input.parentNode
);
input.classList.add("flex-1");
audio_in_button.classList.add("ml-2");
audio_in_button.addEventListener("click", () => {
if (isStarted) {
recognition.stop();
isStarted = false;
} else {
recognition.lang = language_select.value;
recognition.start();
isStarted = true;
}
});
recognition.addEventListener("result", (event) => {
let transcript = "";
for (const result of event.results) {
transcript += result[0].transcript;
}
if (transcript != "") {
input.value = transcript;
}
});
recognition.addEventListener("start", () => {
audio_in_button.style.backgroundColor = "red";
audio_in_button.style.boxShadow = "2px 2px 0.5px #808080";
});
recognition.addEventListener("end", () => {
audio_in_button.style.backgroundColor = "";
audio_in_button.style.boxShadow = "";
});
}
}
}

View File

@ -1,323 +0,0 @@
// Dirty fix for disabling speech synth for firefox browsers :()
const userAgent = navigator.userAgent;
async function copyToClipboard(text) {
try {
await navigator.clipboard.writeText(text);
console.log('Text copied to clipboard');
} catch (err) {
console.error('Failed to copy text: ', err);
}
}
function addMessage(sender, message, id, rank = 0, can_edit = false) {
const chatWindow = document.getElementById('chat-window');
const chatForm = document.getElementById('chat-form');
const userInput = document.getElementById('user-input');
const messageElement = document.createElement('div');
messageElement.classList.add('bg-secondary', 'drop-shadow-sm', 'p-4', 'mx-6', 'my-4', 'flex', 'flex-col', 'space-x-2', 'rounded-lg', 'shadow-lg', 'bg-gray-300', 'text-black', 'dark:text-gray-200', 'dark:bg-gray-800', 'hover:bg-gray-400', 'dark:hover:bg-gray-700', 'transition-colors', 'duration-300');
messageElement.id = id
//messageElement.classList.add(sender);
messageElement.setAttribute('id', id);
const senderElement = document.createElement('div');
senderElement.classList.add('font-normal', 'underline', 'text-sm');
senderElement.innerHTML = sender;
const messageTextElement = document.createElement('div');
messageTextElement.classList.add('font-medium', 'text-md', 'whitespace-pre-wrap');
messageTextElement.innerHTML = message;
// Create a hidden div element needed to buffer responses before commiting them to the visible message
const hiddenElement = document.createElement('div');
hiddenElement.style.display = 'none';
hiddenElement.innerHTML = '';
messageElement.appendChild(senderElement);
messageElement.appendChild(messageTextElement);
if (can_edit) {
// Create buttons container
const buttonsContainer = document.createElement('div');
// Add the 'flex' class to the div
buttonsContainer.classList.add('flex');
// Add the 'justify-end' class to the div
buttonsContainer.classList.add('justify-end');
// Set the width and height of the container to 100%
buttonsContainer.style.width = '100%';
buttonsContainer.style.height = '100%';
const clipboardButton = document.createElement('button');
clipboardButton.classList.add('bg-gray-500', 'hover:bg-gray-700', 'text-white', 'font-bold', 'py-0', 'px-0', "w-10", "h-10");
clipboardButton.style.float = 'right'; // set the float property to right
clipboardButton.style.display = 'inline-block'
clipboardButton.innerHTML = '';
const clipboardImg = document.createElement('img');
clipboardImg.src = "/static/images/copy.png";
clipboardImg.classList.add('py-1', 'px-1', 'rounded', 'w-10', 'h-10');
clipboardButton.title = "clipboard message";
clipboardButton.appendChild(clipboardImg)
clipboardButton.addEventListener('click', () => {
copyToClipboard(messageTextElement.innerText)
})
const resendButton = document.createElement('button');
resendButton.classList.add('bg-gray-500', 'hover:bg-gray-700', 'text-white', 'font-bold', 'py-0', 'px-0', "w-10", "h-10");
resendButton.style.float = 'right'; // set the float property to right
resendButton.style.display = 'inline-block'
resendButton.innerHTML = '';
const resendImg = document.createElement('img');
resendImg.src = "/static/images/refresh.png";
resendImg.classList.add('py-1', 'px-1', 'rounded', 'w-10', 'h-10');
resendButton.title = "Resend message";
resendButton.appendChild(resendImg)
resendButton.addEventListener('click', () => {
// get user input and clear input field
message = userInput.value;
userInput.value = '';
// add user message to chat window
const sendbtn = document.querySelector("#submit-input")
const waitAnimation = document.querySelector("#wait-animation")
const stopGeneration = document.querySelector("#stop-generation")
sendbtn.style.display = "none";
waitAnimation.style.display = "block";
stopGeneration.style.display = "block";
globals.bot_msg = addMessage("", "", 0, 0, can_edit = true);
globals.user_msg = undefined
// scroll to bottom of chat window
chatWindow.scrollTop = chatWindow.scrollHeight;
send_message('generate_msg_from',{prompt: message, id: messageElement.id})
});
const editButton = document.createElement('button');
editButton.classList.add('bg-gray-500', 'hover:bg-gray-700', 'text-white', 'font-bold', 'py-0', 'px-0', "w-10", "h-10", "rounded-l");
editButton.style.float = 'right'; // set the float property to right
editButton.style.display = 'inline-block'
editButton.innerHTML = '';
const editImg = document.createElement('img');
editImg.src = "/static/images/edit_discussion.png";
editImg.classList.add('py-1', 'px-1', 'rounded', 'w-10', 'h-10');
editButton.title = "Edit message";
editButton.appendChild(editImg)
editButton.addEventListener('click', () => {
const inputBlock = document.createElement('div')
inputBlock.classList.add('flex','flex-col');
const inputField = document.createElement('textarea');
inputField.type = 'text';
inputField.classList.add('font-medium', 'resize-y','h-24', 'text-md', 'border', 'border-gray-300', 'p-1');
inputField.value = messageTextElement.innerText;
//buttonsContainer.style.display = "none"
const saveButton = document.createElement('button');
saveButton.classList.add('bg-gray-500', 'hover:bg-gray-700', 'text-white', 'font-bold', 'py-2', 'px-4', 'my-2', 'ml-2');
saveButton.innerHTML = 'Save';
inputBlock.appendChild(inputField)
inputBlock.appendChild(saveButton)
saveButton.addEventListener('click', () => {
const newText = inputField.value;
messageTextElement.innerText = newText;
// make request to update message
const url = `/update_message?id=${id}&message=${newText}`;
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
else {
console.log("Updated")
}
})
.catch(error => {
console.error('There was a problem updating the message:', error);
});
//buttonsContainer.style.display = 'block'
messageElement.replaceChild(messageTextElement, inputBlock);
//messageElement.removeChild(inputField);
messageElement.removeChild(saveButton);
});
messageElement.replaceChild(inputBlock, messageTextElement);
inputField.focus();
});
const deleteButton = document.createElement('button');
deleteButton.classList.add('bg-gray-500', 'hover:bg-gray-700', 'text-white', 'font-bold', 'py-0', 'px-0', "w-10", "h-10");
deleteButton.style.float = 'right'; // set the float property to right
deleteButton.style.display = 'inline-block'
deleteButton.innerHTML = '';
const deleteImg = document.createElement('img');
deleteImg.src = "/static/images/delete_discussion.png";
deleteImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
deleteButton.title = "Delete message";
deleteButton.appendChild(deleteImg)
deleteButton.addEventListener('click', () => {
const url = `/delete_message?id=${id}`;
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data.new_rank)
messageElement.style.display = "none"
})
.catch(error => {
console.error('There was a problem updating the message:', error);
});
});
const rank_up = document.createElement('button');
rank_up.classList.add('bg-gray-500', 'hover:bg-gray-700', 'text-white', 'font-bold', 'py-0', 'px-0', "w-10", "h-10");
rank_up.title = "Upvote";
rank_up.style.float = 'right'; // set the float property to right
rank_up.style.display = 'inline-block'
rank_up.innerHTML = '';
const thumbUpImg = document.createElement('img');
thumbUpImg.src = "/static/images/thumb_up.png";
thumbUpImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
rank_up.appendChild(thumbUpImg)
const thumbUpBadge = document.createElement('span');
thumbUpBadge.innerText = "";
thumbUpBadge.classList.add('inline-flex', 'items-center', 'justify-center', 'h-4', 'w-4', 'rounded-full', 'bg-red-500', 'text-white', 'text-xs', 'top-0', 'right-0');
rank_up.appendChild(thumbUpBadge)
rank_up.addEventListener('click', () => {
const url = `/message_rank_up?id=${id}`;
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data.new_rank)
if (data.new_rank > 0) {
thumbUpBadge.innerText = `${data.new_rank}`
thumbDownBadge.innerText = ``
thumbUpBadge.display = `block`
thumbDownBadge.display = 'none'
}
else if (data.new_rank < 0) {
thumbUpBadge.innerText = ``
thumbDownBadge.innerText = `${data.new_rank}`
thumbUpBadge.display = `none`
thumbDownBadge.display = 'block'
}
else {
thumbUpBadge.innerText = ``
thumbDownBadge.innerText = ``
thumbUpBadge.display = `none`
thumbDownBadge.display = 'none'
}
})
.catch(error => {
console.error('There was a problem updating the message:', error);
});
});
const rank_down = document.createElement('button');
rank_down.classList.add('bg-gray-500', 'hover:bg-gray-700', 'text-white', 'font-bold', 'py-0', 'px-0', "w-10", "h-10");
rank_down.title = "Downvote";
rank_down.style.float = 'right'; // set the float property to right
rank_down.style.display = 'inline-block'
rank_down.innerHTML = '';
const thumbDownImg = document.createElement('img');
thumbDownImg.src = "/static/images/thumb_down.png";
thumbDownImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
rank_down.appendChild(thumbDownImg)
const thumbDownBadge = document.createElement('span');
thumbDownBadge.innerText = "";
thumbDownBadge.classList.add('inline-flex', 'items-center', 'justify-center', 'h-4', 'w-4', 'rounded-full', 'bg-red-500', 'text-white', 'text-xs', 'top-0', 'right-0');
rank_down.appendChild(thumbDownBadge)
rank_down.addEventListener('click', () => {
const url = `/message_rank_down?id=${id}`;
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data)
if (data.new_rank > 0) {
thumbUpBadge.innerText = `${data.new_rank}`
thumbDownBadge.innerText = ``
thumbUpBadge.display = `block`
thumbDownBadge.display = 'none'
}
else if (data.new_rank < 0) {
thumbUpBadge.innerText = ``
thumbDownBadge.innerText = `${data.new_rank}`
thumbUpBadge.display = `none`
thumbDownBadge.display = 'block'
}
else {
thumbUpBadge.innerText = ``
thumbDownBadge.innerText = ``
thumbUpBadge.display = `none`
thumbDownBadge.display = 'none'
}
})
.catch(error => {
console.error('There was a problem updating the message:', error);
});
});
buttonsContainer.appendChild(editButton);
buttonsContainer.appendChild(clipboardButton);
buttonsContainer.appendChild(resendButton);
buttonsContainer.appendChild(deleteButton);
buttonsContainer.appendChild(rank_up);
buttonsContainer.appendChild(rank_down);
messageElement.appendChild(buttonsContainer);
// Dirty fix for disabling speech synth for firefox browsers :()
if (!userAgent.match(/firefox|fxios/i)) {
attachAudio_modules(messageTextElement, buttonsContainer);
}
if (rank > 0) {
thumbUpBadge.innerText = `${rank}`
thumbDownBadge.innerText = ``
thumbUpBadge.display = `block`
thumbDownBadge.display = 'none'
}
else if (rank < 0) {
thumbUpBadge.innerText = ``
thumbDownBadge.innerText = `${rank}`
thumbUpBadge.display = `none`
thumbDownBadge.display = 'block'
}
else {
thumbUpBadge.innerText = ``
thumbDownBadge.innerText = ``
thumbUpBadge.display = `none`
thumbDownBadge.display = 'none'
}
chatWindow.buttonsContainer = buttonsContainer
}
else{
chatWindow.buttonsContainer = undefined
}
chatWindow.appendChild(messageElement);
chatWindow.appendChild(hiddenElement);
// scroll to bottom of chat window
chatWindow.scrollTop = chatWindow.scrollHeight;
messageElement.messageTextElement = messageTextElement
messageElement.hiddenElement = hiddenElement
messageElement.senderElement = senderElement
messageElement.messageTextElement = messageTextElement
messageElement.id = id
messageElement.setID=(id)=>{
messageElement.id = id
}
messageElement.setSender=(sender)=>{
messageElement.senderElement.innerHTML = sender
}
messageElement.setMessage=(message)=>{
messageElement.messageTextElement.innerHTML = message
}
// Return all needed stuff
return messageElement
}

View File

@ -1,55 +0,0 @@
function db_export(){
const chatWindow = document.getElementById('chat-window');
const exportButton = document.getElementById('export-button');
exportButton.title = "Export database";
exportButton.addEventListener('click', () => {
const messages = Array.from(chatWindow.querySelectorAll('.message')).map(messageElement => {
const senderElement = messageElement.querySelector('.sender');
const messageTextElement= messageElement.querySelector('.message-text');
const sender = senderElement.textContent;
const messageText = messageTextElement.textContent;
return { sender, messageText };
});
const exportFormat = 'json'; // replace with desired export format
if (exportFormat === 'text') {
const exportText = messages.map(({ sender, messageText }) => `${sender}: ${messageText}`).join('\n');
downloadTextFile(exportText);
} else if (exportFormat === 'json') {
fetch('/export')
.then(response => response.json())
.then(data => {
db_data = JSON.stringify(data)
// Do something with the data, such as displaying it on the page
console.log(db_data);
downloadJsonFile(db_data);
})
.catch(error => {
// Handle any errors that occur
console.error(error);
});
} else {
console.error(`Unsupported export format: ${exportFormat}`);
}
});
function downloadTextFile(text) {
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
downloadUrl(url);
}
function downloadJsonFile(json) {
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
downloadUrl(url);
}
function downloadUrl(url) {
const link = document.createElement('a');
link.href = url;
link.download = 'discussions.json';
link.click();
}
}

View File

@ -1,270 +0,0 @@
function load_discussion(discussion=0){
var chatWindow = document.getElementById('chat-window');
if(discussion)
{
console.log(discussion.id)
body = { id: discussion.id }
}
else{
body = { }
}
// send query with discussion id to reveal discussion messages
fetch('/load_discussion', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
})
.then(response => {
if (response.ok) {
response.text().then(data => {
const messages = JSON.parse(data);
console.log(messages)
// process messages
chatWindow.innerHTML = '';
messages.forEach(message => {
console.log(`Adding message ${message.type}`)
if(message.type==0){
console.log("Showing message")
addMessage(message.sender, message.content, message.id, message.rank, true);
// scroll to bottom of chat window
chatWindow.scrollTop = chatWindow.scrollHeight;
}
});
});
} else {
alert('Failed to query the discussion');
}
})
.catch(error => {
console.error('Failed to get messages:', error);
alert('Failed to get messages');
});
}
function populate_discussions_list()
{
// Populate discussions list
const discussionsList = document.getElementById('discussions-list');
discussionsList.innerHTML = "";
fetch('/list_discussions')
.then(response => response.json())
.then(discussions => {
discussions.forEach(discussion => {
const buttonWrapper = document.createElement('div');
//buttonWrapper.classList.add('flex', 'space-x-2', 'mt-2');
buttonWrapper.classList.add('drop-shadow-sm', 'p-1', 'mx-2', 'my-2', 'flex', 'flex-row', 'space-x-2', 'rounded-lg', 'shadow-lg', 'bg-gray-200', 'dark:bg-gray-800', 'transition-colors', 'duration-300', 'text-left');
const renameButton = document.createElement('button');
renameButton.classList.add('bg-gray-400', 'hover:bg-gray-800', 'dark:hover:bg-gray-700', 'text-white', 'dark:text-white', 'font-bold', 'py-0', 'px-0', 'rounded',"w-10","h-10");
const renameImg = document.createElement('img');
renameImg.src = "/static/images/edit_discussion.png";
renameButton.title = "Rename discussion";
renameImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
renameButton.appendChild(renameImg);
//renameButton.style.backgroundImage = "/rename_discussion.svg"; //.textContent = 'Rename';
renameButton.addEventListener('click', () => {
const dialog = document.createElement('dialog');
dialog.classList.add('bg-gray-500', 'text-white', 'rounded', 'p-4');
const inputLabel = document.createElement('label');
inputLabel.textContent = 'New name: ';
const inputField = document.createElement('input');
inputField.classList.add('border', "px-2", "mx-2", 'bg-gray-800', 'border-gray-400', 'rounded', 'py-1', 'px-2');
inputField.setAttribute('type', 'text');
inputField.setAttribute('name', 'title');
inputField.setAttribute('value', discussion.title);
inputLabel.appendChild(inputField);
dialog.appendChild(inputLabel);
const cancelButton = document.createElement('button');
cancelButton.textContent = 'Cancel';
cancelButton.addEventListener('click', () => {
dialog.close();
});
const renameConfirmButton = document.createElement('button');
renameConfirmButton.classList.add('bg-gray-500', 'hover:bg-gray-700', 'text-white', 'dark:text-white', 'font-bold', 'py-1', 'px-0', 'rounded', 'ml-2');
renameConfirmButton.textContent = 'Rename';
renameConfirmButton.addEventListener('click', () => {
const newTitle = inputField.value;
if (newTitle === '') {
alert('New name cannot be empty');
} else {
fetch('/rename', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: discussion.id, title: newTitle })
})
.then(response => {
if (response.ok) {
discussion.title = newTitle;
discussionButton.textContent = newTitle;
dialog.close();
} else {
alert('Failed to rename discussion');
}
})
.catch(error => {
console.error('Failed to rename discussion:', error);
alert('Failed to rename discussion');
});
}
});
dialog.appendChild(cancelButton);
dialog.appendChild(renameConfirmButton);
document.body.appendChild(dialog);
dialog.showModal();
});
const deleteButton = document.createElement('button');
deleteButton.classList.add('bg-gray-400', 'hover:bg-gray-800', 'dark:hover:bg-gray-700', 'text-black', 'dark:text-white', 'font-bold', 'py-0', 'px-0', 'rounded',"w-10","h-10");
const deleteImg = document.createElement('img');
deleteImg.src = "/static/images/delete_discussion.png";
deleteButton.title = "Delete discussion";
deleteImg.classList.add('py-2', 'px-2', 'rounded', 'w-15', 'h-15');
deleteButton.addEventListener('click', () => {
fetch('/delete_discussion', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: discussion.id})
})
.then(response => {
if (response.ok) {
buttonWrapper.remove();
} else {
alert('Failed to delete discussion');
}
})
.catch(error => {
console.error('Failed to delete discussion:', error);
alert('Failed to delete discussion');
});
});
deleteButton.appendChild(deleteImg);
const discussionButton = document.createElement('button');
discussionButton.id = discussion.id;
discussionButton.classList.add('isButton', 'hover:bg-gray-800', 'dark:hover:bg-gray-700', 'text-black', 'dark:text-white', 'font-bold', 'py-2', 'px-4', 'rounded', 'ml-2', 'w-full');
discussionButton.textContent = discussion.title;
discussionButton.title = "Open discussion";
//Indicates currently selected (Active) discussion
discussionButton.addEventListener('click', () => {
console.log(`Showing messages for discussion ${discussion.id}`);
load_discussion(discussion);
const btnElList = document.querySelectorAll('.isButton');
btnElList.forEach(element => {
if (element.classList.contains('activeDiscussion')) {
element.classList.remove('activeDiscussion');
}
});
discussionButton.classList.add('activeDiscussion');
});
const btnElList = document.querySelectorAll('.isButton');
btnElList.forEach(btnEl => {
btnEl.addEventListener('click', () => {
btnEl.querySelector('activeDiscussion')?.classList.remove('activeDiscussion');
});
})
buttonWrapper.appendChild(renameButton);
buttonWrapper.appendChild(deleteButton);
buttonWrapper.appendChild(discussionButton);
discussionsList.appendChild(buttonWrapper);
});
})
.catch(error => {
console.error('Failed to get discussions:', error);
alert('Failed to get discussions');
});
}
function populate_menu(){
// adding export discussion button
const exportDiscussionButton = document.querySelector('#export-discussion-button');
exportDiscussionButton.title = "Export discussion to a file";
exportDiscussionButton.addEventListener('click', () => {
fetch(`/export_discussion`)
.then(response => response.json())
.then(data => {
discussion_text = data["discussion_text"]
copyToClipboard(discussion_text)
const filename = window.prompt('Please enter a filename:', 'discussion.txt');
if (filename !== null) {
const text = discussion_text;
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.click();
URL.revokeObjectURL(url);
}
}).catch(function(error){
});
});
const actionBtns = document.querySelector('#action-buttons');
actionBtns.appendChild(exportDiscussionButton);
const newDiscussionBtn = document.querySelector('#new-discussion-btn');
newDiscussionBtn.title = "Create new discussion";
const resetDBButton = document.querySelector('#reset-discussions-btn');
resetDBButton.title = "Reset all discussions/database";
resetDBButton.addEventListener('click', () => {
});
newDiscussionBtn.addEventListener('click', () => {
const chatWindow = document.getElementById('chat-window');
const discussionName = prompt('Enter a name for the new discussion:');
if (discussionName) {
const sendbtn = document.querySelector("#submit-input")
const waitAnimation = document.querySelector("#wait-animation")
const stopGeneration = document.querySelector("#stop-generation")
sendbtn.style.display="none";
waitAnimation.style.display="block";
stopGeneration.style.display="block";
// Add the discussion to the discussion list
const discussionItem = document.createElement('li');
discussionItem.textContent = discussionName;
fetch(`/new_discussion?title=${discussionName}`)
.then(response => response.json())
.then(data => {
console.log(`New chat ${data.welcome_message}`)
// Select the new discussion
//selectDiscussion(discussionId);
chatWindow.innerHTML=""
addMessage(data.sender, data.welcome_message,0);
populate_discussions_list()
sendbtn.style.display="block";
waitAnimation.style.display="none";
stopGeneration.style.display="none";
})
.catch(error => {
// Handle any errors that occur
console.error(error);
});
}
});
}

View File

@ -1,15 +0,0 @@
document.getElementById('extensions-link').addEventListener('click', loadExtensionsPage);
function loadExtensionsPage(event) {
event.preventDefault(); // Prevent the default link behavior
fetch('/extensions')
.then(response => response.text())
.then(html => {
document.getElementById('extensions').innerHTML = html;
})
.catch(error => {
console.error('Error loading extensions page:', error);
});
}

View File

@ -1,15 +0,0 @@
document.getElementById('help-link').addEventListener('click', loadHelpPage);
function loadHelpPage(event) {
event.preventDefault(); // Prevent the default link behavior
fetch('/help')
.then(response => response.text())
.then(html => {
document.getElementById('help').innerHTML = html;
})
.catch(error => {
console.error('Error loading help page:', error);
});
}

View File

@ -1,58 +0,0 @@
function update_main(){
globals.chatWindow = document.getElementById('chat-window');
globals.chatForm = document.getElementById('chat-form');
globals.userInput = document.getElementById('user-input');
globals.stopGeneration = document.getElementById("stop-generation")
globals.sendbtn = document.querySelector("#submit-input")
globals.waitAnimation = document.querySelector("#wait-animation")
globals.stopGeneration.addEventListener('click', (event) =>{
event.preventDefault();
console.log("Stop clicked");
fetch('/stop_gen')
.then(response => response.json())
.then(data => {
console.log(data);
globals.is_generating = true
});
})
function submit_form(){
console.log("Submitting")
// get user input and clear input field
message = globals.userInput.value;
globals.userInput.value = '';
globals.sendbtn.style.display="none";
globals.waitAnimation.style.display="block";
globals.stopGeneration.style.display = "block";
console.log("Sending message to bot")
globals.user_msg = addMessage('',message, 0, 0, can_edit=true);
globals.bot_msg = addMessage('', '', 0, 0, can_edit=true);
// scroll to bottom of chat window
globals.chatWindow.scrollTop = globals.chatWindow.scrollHeight;
send_message('generate_msg',{prompt: message})
//socket.emit('stream-text', {text: text});
}
globals.chatForm.addEventListener('submit', event => {
event.preventDefault();
submit_form();
});
globals.userInput.addEventListener("keyup", function(event) {
// Check if Enter key was pressed while holding Shift
// Also check if Shift + Ctrl keys were pressed while typing
// These combinations override the submit action
const shiftPressed = event.shiftKey;
const ctrlPressed = event.ctrlKey && !event.metaKey;
if ((!shiftPressed) && event.key === "Enter") {
submit_form();
}
});
}

File diff suppressed because one or more lines are too long

View File

@ -1,391 +0,0 @@
function selectOptionByText(selectElement, optionText) {
for (let i = 0; i < selectElement.options.length; i++) {
if (selectElement.options[i].text === optionText) {
selectElement.selectedIndex = i;
break;
}
}
}
fetch('/settings')
.then(response => response.text())
.then(html => {
document.getElementById('settings').innerHTML = html;
bindingInput = document.getElementById('binding');
modelInput = document.getElementById('model');
personalityLanguageInput = document.getElementById('personalities_language');
personalityCategoryInput = document.getElementById('personalities_category');
personalityInput = document.getElementById('personalities');
languageInput = document.getElementById('language');
voiceInput = document.getElementById('voice');
seedInput = document.getElementById('seed');
tempInput = document.getElementById('temperature');
nPredictInput = document.getElementById('n-predict');
topKInput = document.getElementById('top-k');
topPInput = document.getElementById('top-p');
repeatPenaltyInput = document.getElementById('repeat-penalty');
repeatLastNInput = document.getElementById('repeat-last-n');
temperatureValue = document.getElementById('temperature-value');
n_predictValue = document.getElementById('n-predict-value');
topkValue = document.getElementById('top-k-value');
toppValue = document.getElementById('top-p-value');
repeatPenaltyValue = document.getElementById('repeat-penalty-value');
repeatLastNValue = document.getElementById('repeat-last-n');
function update_config(){
fetch('/get_config')
.then((response) => response.json())
.then((data) => {
console.log("Received config")
console.log(data);
selectOptionByText(bindingInput, data["binding"])
selectOptionByText(modelInput, data["model"])
selectOptionByText(personalityLanguageInput, data["personality_language"])
selectOptionByText(personalityCategoryInput, data["personality_category"])
selectOptionByText(personalityInput, data["personality"])
languageInput.value = data["language"]
voiceInput.value = data["voice"]
seedInput.value = data["seed"]
tempInput.value = data["temperature"]
nPredictInput.value = data["n_predict"]
topKInput.value = data["top_k"]
topPInput.value = data["top_p"]
repeatPenaltyInput.textContent = data["repeat_penalty"]
repeatLastNInput.textContent = data["repeat_last_n"]
temperatureValue.textContent =`Temperature(${data["temperature"]})`
n_predictValue.textContent =`N Predict(${data["n_predict"]})`
topkValue.textContent =`Top-K(${data["top_k"]})`
toppValue.textContent =`Top-P(${data["top_p"]})`
repeatPenaltyValue.textContent =`Repeat penalty(${data["repeat_penalty"]})`
repeatLastNValue.textContent =`Repeat last N(${data["repeat_last_n"]})`
})
.catch((error) => {
console.error('Error:', error);
});
}
bindingInput.addEventListener('input',() => {
console.log(`Binding (${bindingInput.value})`)
// Use fetch to send form values to Flask endpoint
fetch('/set_binding', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({"binding":bindingInput.value}),
})
.then((response) => response.json())
.then((data) => {
console.log(data);
if(data["status"]==="no_models_found"){
alert("No models found for this binding. Make sure you select a binding that you have models for or download models from links in our repository")
}
else{
populate_settings();
alert("Binding set successfully")
}
})
.catch((error) => {
console.error('Error:', error);
alert("Error setting configuration")
});
})
modelInput.addEventListener('input',() => {
console.log(`Model (${modelInput.value})`)
// Use fetch to send form values to Flask endpoint
fetch('/set_model', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({"model":modelInput.value}),
})
.then((response) => response.json())
.then((data) => {
console.log(data);
populate_settings();
alert("Binding set successfully")
})
.catch((error) => {
console.error('Error:', error);
alert("Error setting configuration")
});
})
tempInput.addEventListener('input',() => {
temperatureValue.textContent =`Temperature(${tempInput.value})`
})
nPredictInput.addEventListener('input',() => {
n_predictValue.textContent =`N Predict(${nPredictInput.value})`
})
topKInput.addEventListener('input',() => {
topkValue.textContent =`Top-K(${topKInput.value})`
})
topPInput.addEventListener('input',() => {
toppValue.textContent =`Top-P(${topPInput.value})`
})
repeatPenaltyInput.addEventListener('input',() => {
repeatPenaltyValue.textContent =`Repeat penalty(${repeatPenaltyInput.value})`
})
repeatLastNInput.addEventListener('input',() => {
repeatLastNValue.textContent =`Repeat last N(${repeatLastNInput.value})`
})
const submitButton = document.getElementById('submit-model-params');
submitButton.addEventListener('click', (event) => {
// Prevent default form submission
event.preventDefault();
// Get form values and put them in an object
const formValues = {
seed: seedInput.value,
binding: bindingInput.value,
model: modelInput.value,
personality_language:personalityLanguageInput.value,
personality_category:personalityCategoryInput.value,
personality: personalityInput.value,
language: languageInput.value,
voice: voiceInput.value,
temperature: tempInput.value,
nPredict: nPredictInput.value,
topK: topKInput.value,
topP: topPInput.value,
repeatPenalty: repeatPenaltyInput.value,
repeatLastN: repeatLastNInput.value
};
console.log(formValues);
// Use fetch to send form values to Flask endpoint
fetch('/update_model_params', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formValues),
})
.then((response) => response.json())
.then((data) => {
console.log(data);
alert("Configuration set successfully")
})
.catch((error) => {
console.error('Error:', error);
alert("Error setting configuration")
});
});
populate_settings();
function populate_settings(){
// Get a reference to the <select> element
const selectBinding = document.getElementById('binding');
const selectModel = document.getElementById('model');
const selectPersonalityLanguage = document.getElementById('personalities_language');
const selectPersonalityCategory = document.getElementById('personalities_category');
const selectPersonality = document.getElementById('personalities');
function populate_bindings(){
selectBinding.innerHTML = "";
// Fetch the list of .bin files from the models subfolder
fetch('/list_bindings')
.then(response => response.json())
.then(data => {
if (Array.isArray(data)) {
// data is an array
data.forEach(filename => {
const optionElement = document.createElement('option');
optionElement.value = filename;
optionElement.textContent = filename;
selectBinding.appendChild(optionElement);
});
// fetch('/get_args')
// .then(response=> response.json())
// .then(data=>{
// })
} else {
console.error('Expected an array, but received:', data);
}
});
}
function populate_models(){
selectModel.innerHTML=""
// Fetch the list of .bin files from the models subfolder
fetch('/list_models')
.then(response => response.json())
.then(data => {
if (Array.isArray(data)) {
// data is an array
data.forEach(filename => {
const optionElement = document.createElement('option');
optionElement.value = filename;
optionElement.textContent = filename;
selectModel.appendChild(optionElement);
});
// fetch('/get_args')
// .then(response=> response.json())
// .then(data=>{
// })
} else {
console.error('Expected an array, but received:', data);
}
});
}
function populate_personalities_languages(){
const selectPersonalityLanguage = document.getElementById('personalities_language');
selectPersonalityLanguage.innerHTML=""
// Fetch the list of .yaml files from the models subfolder
fetch('/list_personalities_languages')
.then(response => response.json())
.then(data => {
if (Array.isArray(data)) {
// data is an array
data.forEach(filename => {
const optionElement = document.createElement('option');
optionElement.value = filename;
optionElement.textContent = filename;
selectPersonalityLanguage.appendChild(optionElement);
});
// fetch('/get_args')
// .then(response=> response.json())
// .then(data=>{
// })
} else {
console.error('Expected an array, but received:', data);
}
});
}
function populate_personalities_categories(){
const selectPersonalityCategory = document.getElementById('personalities_category');
selectPersonalityCategory.innerHTML=""
// Fetch the list of .yaml files from the models subfolder
fetch('/list_personalities_categories')
.then(response => response.json())
.then(data => {
if (Array.isArray(data)) {
// data is an array
data.forEach(filename => {
const optionElement = document.createElement('option');
optionElement.value = filename;
optionElement.textContent = filename;
selectPersonalityCategory.appendChild(optionElement);
});
} else {
console.error('Expected an array, but received:', data);
}
});
}
function populate_personalities(){
const selectPersonalityLanguage = document.getElementById('personalities_language');
selectPersonality.innerHTML=""
// Fetch the list of .yaml files from the models subfolder
fetch('/list_personalities')
.then(response => response.json())
.then(data => {
if (Array.isArray(data)) {
// data is an array
data.forEach(filename => {
const optionElement = document.createElement('option');
optionElement.value = filename;
optionElement.textContent = filename;
selectPersonality.appendChild(optionElement);
});
} else {
console.error('Expected an array, but received:', data);
}
});
}
function set_personality_language(lang, callback) {
fetch(`/set_personality_language?language=${lang}`)
.then(response => response.json())
.then(data => {
callback(data);
});
}
// Example usage: call another function after set_personality_language returns
selectPersonalityLanguage.addEventListener('click', function() {
set_personality_language(selectPersonalityLanguage.value, function(data) {
console.log('Response received:', data);
populate_personalities_categories();
});
});
function set_personality_category(category, callback) {
fetch(`/set_personality_category?category=${category}`)
.then(response => response.json())
.then(data => {
callback()
});
}
// Example usage: call another function after set_personality_category returns
selectPersonalityCategory.addEventListener('click', function() {
set_personality_category(selectPersonalityCategory.value, function(data) {
console.log('Response received:', data);
populate_personalities();
});
});
populate_bindings()
populate_models()
populate_personalities_languages()
populate_personalities_categories()
populate_personalities()
setTimeout(update_config,100);
// Fetch the list of .yaml files from the models subfolder
fetch('/list_languages')
.then(response => response.json())
.then(data => {
if (Array.isArray(data)) {
// data is an array
const selectLanguage = document.getElementById('language');
data.forEach(row => {
const optionElement = document.createElement('option');
optionElement.value = row.value;
optionElement.innerHTML = row.label;
selectLanguage.appendChild(optionElement);
});
} else {
console.error('Expected an array, but received:', data);
}
});
}
})
.catch(error => {
console.error('Error loading settings page:', error);
});

File diff suppressed because it is too large Load Diff

View File

@ -1,46 +0,0 @@
function showTab(tabId) {
// hide all tabs
var tabs = document.getElementsByClassName('tab-pane');
for (var i = 0; i < tabs.length; i++) {
tabs[i].style.display = 'none';
}
// show the selected tab
console.log(tabId)
var tab = document.getElementById(tabId);
tab.style.display = 'block';
}
// show the main tab by default
showTab('main');
// add event listeners to the tab links
var tabLinks = document.getElementsByTagName('a');
for (var i = 0; i < tabLinks.length; i++) {
tabLinks[i].addEventListener('click', function (event) {
event.preventDefault();
var tabId = this.getAttribute('href').substring(1);
showTab(tabId);
});
}
fetch('/main')
.then(response => response.text())
.then(html => {
document.getElementById('main').innerHTML = html;
// First time we populate the discussions list
populate_discussions_list()
populate_menu();
load_discussion();
update_main();
db_export();
// Dirty fix for disabling speech synth for firefox browsers :()
if (!userAgent.match(/firefox|fxios/i)) {
prepre_audio();
add_audio_in_ui();
populateVoicesList();
}
})
.catch(error => {
console.error('Error loading main page:', error);
});

View File

@ -1,8 +0,0 @@
// Default starts with dark mode.
document.documentElement.classList.add('dark');
// Changes theme based on user's device preference when page is loaded.
if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
} else {
document.documentElement.classList.remove('dark')
}

View File

@ -1,46 +0,0 @@
var themeToggleDarkIcon = document.getElementById(
"theme-toggle-dark-icon"
);
var themeToggleLightIcon = document.getElementById(
"theme-toggle-light-icon"
);
// Change the icons inside the button based on previous settings
if (
localStorage.getItem("color-theme") === "dark" ||
(!("color-theme" in localStorage) &&
window.matchMedia("(prefers-color-scheme: dark)").matches)
) {
themeToggleLightIcon.classList.remove("hidden");
} else {
themeToggleDarkIcon.classList.remove("hidden");
}
var themeToggleBtn = document.getElementById("theme-toggle");
themeToggleBtn.addEventListener("click", function () {
// toggle icons inside button
themeToggleDarkIcon.classList.toggle("hidden");
themeToggleLightIcon.classList.toggle("hidden");
// if set via local storage previously
if (localStorage.getItem("color-theme")) {
if (localStorage.getItem("color-theme") === "light") {
document.documentElement.classList.add("dark");
localStorage.setItem("color-theme", "dark");
} else {
document.documentElement.classList.remove("dark");
localStorage.setItem("color-theme", "light");
}
// if NOT set via local storage previously
} else {
if (document.documentElement.classList.contains("dark")) {
document.documentElement.classList.remove("dark");
localStorage.setItem("color-theme", "light");
} else {
document.documentElement.classList.add("dark");
localStorage.setItem("color-theme", "dark");
}
}
});

View File

@ -1,15 +0,0 @@
document.getElementById('training-link').addEventListener('click', loadHelpPage);
function loadHelpPage(event) {
event.preventDefault(); // Prevent the default link behavior
fetch('/training')
.then(response => response.text())
.then(html => {
document.getElementById('training').innerHTML = html;
})
.catch(error => {
console.error('Error loading help page:', error);
});
}

View File

@ -1,89 +0,0 @@
// Project : lollms-webui
// Author : ParisNeo
// Description :
// All websocket stuff can be found here.
var globals={
is_generating:false,
chatWindow:undefined,
chatForm:undefined,
userInput:undefined,
stopGeneration:undefined,
sendbtn:undefined,
waitAnimation:undefined
}
var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);
socket.on('connect', function() {
console.log("Disconnected")
});
// Handle reconnection attempt failure
socket.on('reconnect_failed', () => {
console.log('All reconnection attempts failed');
// You can perform any custom actions or error handling here
});
// Handle reconnection attempt
socket.on('reconnect_attempt', () => {
reconnectionAttempt++;
console.log(`Reconnection attempt ${reconnectionAttempt}...`);
// You can perform custom actions or error handling for each attempt here
});
socket.on('disconnect', function() {
console.log("Disconnected")
});
socket.on('infos', function(msg) {
console.log(msg)
if(msg["status"]=="generation_started"){
if(globals.user_msg){
globals.user_msg.setSender(msg.user);
globals.user_msg.setMessage(msg.message);
globals.user_msg.setID(msg.id);
}
globals.bot_msg.setSender(msg.bot);
globals.bot_msg.setID(msg.ai_message_id);
globals.bot_msg.messageTextElement.innerHTML = `Generating answer. Please stand by...`;
}
else{
globals.sendbtn.style.display="block";
globals.waitAnimation.style.display="none";
globals.stopGeneration.style.display = "none";
globals.is_generating = false
alert("It seems that no model has been loaded. Please download and install a model first, then try again.");
}
});
socket.on('waiter', function(msg) {
globals.bot_msg.messageTextElement.innerHTML = `Generating answer. Please stand by...`;
});
socket.on('message', function(msg) {
text = msg.data;
// For the other enrtries, these are just the text of the chatbot
globals.bot_msg.messageTextElement.innerHTML = marked.marked(text);
// scroll to bottom of chat window
globals.chatWindow.scrollTop = globals.chatWindow.scrollHeight;
});
socket.on('final',function(msg){
text = msg.data;
globals.bot_msg.hiddenElement.innerHTML = text
globals.bot_msg.messageTextElement.innerHTML = marked.marked(text)
globals.sendbtn.style.display="block";
globals.waitAnimation.style.display="none";
globals.stopGeneration.style.display = "none";
globals.is_generating = false
});
globals.socket = socket
globals.is_generating = false
function send_message(service_name, parameters){
if(!globals.is_generating){
globals.socket.emit(service_name, parameters);
globals.is_generating = true
}
}

View File

@ -1,18 +0,0 @@
<form id="model-params-form" class="bg-gray-50 dark:bg-gray-700 shadow-md rounded px-8 py-8 pt-6 pb-8 mb-4 text-black dark:text-white">
<div></div>
<div class="mb-4">
<button type="submit" id="submit-model-params" class="my-1 mx-1 outline-none px-4 bg-accent rounded-md bg-gray-500 hover:bg-gray-300 transition-colors ease-in-out">save extensions settings</button>
</div>
</form>
<footer class="bottom-0 text-black dark:text-white">
This section is under development. Stay tuned.<br>
To have a glimpse of what extensions and options will be added, please look at my chatgpt-personality-selector google chrome extension:<br>
<br>
* <a href="https://chrome.google.com/webstore/detail/chatgpt-personality-selec/jdmpccdlifdkhniemenfmieffkdblahk?hl=en">https://chrome.google.com/webstore/detail/chatgpt-personality-selec/jdmpccdlifdkhniemenfmieffkdblahk?hl=en</a>
<br>
<br>
After installing the extension, go to <a href="chat.openai.com/chat"/> and the extension popup will apear.<br>
All personalities will be implemented to gpt4All and can be used with any llamacpp or gpt-j model.
</footer>

View File

@ -1,119 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Help | lollms-webui</title>
<!-- Include Tailwind CSS -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/utilities.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/tailwind.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/tailwindcss.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/tailwind-dark.min.css') }}">
<!-- Include custom CSS -->
<link rel="stylesheet" href="{{ url_for('static', filename='css/help.css') }}">
</head>
<body>
<!-- Navbar -->
<nav class="flex justify-between items-center bg-gray-200 dark:bg-gray-900 text-black dark:text-white p-4">
<a href="/" class="text-lg font-bold">lollms-webui</a>
<!-- Dropdown menu -->
<div class="relative">
<button class="flex items-center text-lg font-bold">
Help
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
class="ml-2 h-5 w-5 transform transition-transform duration-300">
<path fill-rule="evenodd"
d="M6.293 6.293a1 1 0 0 0-1.414 1.414L8.586 12l-3.707 3.293a1 1 0 1 0 1.414 1.414l4-4a1 1 0 0 0 0-1.414l-4-4a1 1 0 0 0-.707-.293zm7.414 0a1 1 0 0 1 1.414 0l4 4a1 1 0 0 1 0 1.414l-4 4a1 1 0 1 1-1.414-1.414L11.414 12l3.293-3.293a1 1 0 0 1 1.414 0z" />
</svg>
</button>
<ul class="absolute right-0 w-40 mt-2 py-2 bg-white rounded-md shadow-xl z-10 hidden">
<li><a href="#credits" class="block px-4 py-2 text-gray-800 hover:bg-gray-100">Credits</a></li>
<li><a href="#how-to-use" class="block px-4 py-2 text-gray-800 hover:bg-gray-100">How to use</a></li>
<li><a href="#faq" class="block px-4 py-2 text-gray-800 hover:bg-gray-100">FAQ</a></li>
<li><a href="#examples" class="block px-4 py-2 text-gray-800 hover:bg-gray-100">Examples</a></li>
</ul>
</div>
</nav>
<!-- Credits section -->
<section id="credits" class="mb-8 ml-4 text-black dark:text-white">
<h2 class="text-2xl font-bold mb-4">Credits</h2>
<p class="mb-4">Here are the developers who worked on this website:</p>
<ul class="list-disc list-inside mb-4">
<li>@ParisNeo : Creator of the project and Lead developer</li>
<li>@AndriyMulyar : CEO of Nomic-ai who offered to link the project as their official ui for LoLLMs</li>
<li><a href="https://github.com/ParisNeo/lollms-webui/graphs/contributors" target="_blank" class="text-blue-900 dark:text-blue-600">A number of very talented open-source developers without whom this project wouldn't be as awesome as it is.</a></li>
<li> We also appreciate the support of the users of this tool who have helped us in various ways.</li>
</ul>
<p class="mb-4">We would also like to acknowledge the following open-source projects that we used:</p>
<ul class="list-disc list-inside mb-4">
<li>pyllamacpp</li>
<li>llamacpp</li>
<li>llama</li>
<li>tailwindcss</li>
</ul>
<p>Thank you to everyone who contributed to the development of this project!</p>
</section>
<!-- How to use section -->
<section id="how-to-use" class="mb-8 ml-4 text-black dark:text-white">
<h2 class="text-2xl font-bold mb-4">How to use</h2>
<ol class="list-decimal list-inside mb-4">
<li>Step 1: Write your prompt.</li>
<li>Step 2: Press enter or click the send button.</li>
<li>Step 3: Read the output.</li>
<li>Step 4: Rank the output if you want or edit it.</li>
<li>Step 5: Continue the discussion untill you have no more queries.</li>
</ol>
<p class="mb-4">Here are some tips and tricks to help you get the most out of this website:</p>
<ul class="list-disc list-inside">
<li>Tip 1: Be specific with your questions.</li>
<li>Tip 2: The model needs to be tamed. So try to put it in the mood to answer your question.</li>
<li>Tip 3: The model can give helarious, false or completely made up responses. So be vigilant not to use the model for sensitive subjects like medication or financial advice</li>
</ul>
</section>
<!-- FAQ section -->
<section id="faq">
<h2 class="text-2xl font-bold mb-4 ml-4 text-black dark:text-white">Frequently Asked Questions (FAQ)</h2>
<dl class="mb-8 ml-4 text-black dark:text-white">
<div class="mb-4">
<dt class="font-bold">How to install?</dt>
<dd>Download the model from the github then use install.bat for windows and install.sh for linux/macOsX.</dd>
</div>
</dl>
</section>
<section id="examples">
<h2 class="text-2xl font-bold mb-4 ml-4 text-black dark:text-white">Usage examples</h2>
<dl class="mb-8 ml-4 text-black dark:text-white">
<div class="mb-4">
<dt class="font-bold">Casual discussion</dt>
<dd>Hello, my name is (put your name here).</dd>
<dt class="font-bold">Color picker for css</dt>
<dd>What is the hex code for the color pink.</dd>
<dt class="font-bold">Movie plot</dt>
<dd>Come up with an interesting idea for a new movie plot. Your plot should be described with a title and a summary.</dd>
<dt class="font-bold">Programming questions</dt>
<dd>Write a python function that reverses a string.</dd>
<dt class="font-bold">Ask about dogs</dt>
<dd>List 10 dogs.</dd>
<dt class="font-bold">Weird stuff</dt>
<dd>Write me a poem about the fall of Julius Ceasar into a ceasar salad in iambic pentameter.</dd>
<dt class="font-bold">Culinary help</dt>
<dd>Act as ChefAI an AI that has the ability to create recipes for any occasion. Instruction: Give me a recipe for my next anniversary.</dd>
<dt class="font-bold">General culture</dt>
<dd>Who is Abraham Lincoln?</dd>
<dt class="font-bold">Writing a letter</dt>
<dd>write a letter to my collegue and tell him I can't make it to work today. Make it humorous.</dd>
<dt class="font-bold">Love poem</dt>
<dd>write a poem about love between two AIs.</dd>
</div>
</dl>
</section>
</div>
</main>
</body>
</html>

View File

@ -1,76 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>LoLLMs - WEBUI</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/utilities.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/tailwind.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/tailwindcss.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/tailwind-dark.min.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/chat.css') }}">
<link rel="shortcut icon" href="{{ url_for('static', filename='images/favicon.ico') }}" type="image/x-icon">
</head>
<body class="w-screen h-500 bg-primary text-gray-400 flex flex-col bg-gray-200 dark:bg-gray-900 h-screen overflow-hidden">
<div class="w-full h-50 border-b-4 border-black dark:border-gray-600 text-2xl font-bold flex justify-between items-center px-6 py-6">
<div class="flex">
<div class="w-12 h-12"><a href="#main"><img src="{{ url_for('static', filename='images/icon.png') }}"></a></div>
<div class="contents">
<button id="theme-toggle" type="button" class="ml-5 bg-gray-200 dark:bg-gray-900 hover:bg-gray-300 dark:hover:bg-gray-500 rounded-lg text-sm p-2.5">
<img id="theme-toggle-dark-icon" class="hidden w-5 h-5" fill="currentColor" viewBox="0 0 20 20" src="{{ url_for('static', filename='images/dark.svg') }}"></img>
<img id="theme-toggle-light-icon" class="hidden w-5 h-5" fill="currentColor" viewBox="0 0 20 20" src="{{ url_for('static', filename='images/light.svg') }}"></img>
</button>
</div>
</div>
<h1 class="text-2xl text-black dark:text-white">LOLLMS - WEBUI</h1>
</div>
<div class="content-center items-center mt-4">
<ul class="flex
content-center items-center">
<li class="mr-1">
<a href="#main" class="bg-gray-50 dark:bg-gray-700 text-black dark:text-gray-200 py-2 px-4 rounded-t-md font-medium hover:bg-gray-800 hover:text-white dark:hover:bg-gray-200 dark:hover:text-black" id="main-link">Main</a>
</li>
<li class="mr-1">
<a href="#settings" class="bg-gray-50 dark:bg-gray-700 text-black dark:text-gray-200 py-2 px-4 rounded-t-md font-medium hover:bg-gray-800 hover:text-white dark:hover:bg-gray-200 dark:hover:text-black" id="settings-link">Settings</a>
</li>
<li class="mr-1">
<a href="#extensions" class="bg-gray-50 dark:bg-gray-700 text-black dark:text-gray-200 py-2 px-4 rounded-t-md font-medium hover:bg-gray-800 hover:text-white dark:hover:bg-gray-200 dark:hover:text-black" id="extensions-link">Extensions</a>
</li>
<li class="mr-1">
<a href="#training" class="bg-gray-50 dark:bg-gray-700 text-black dark:text-gray-200 py-2 px-4 rounded-t-md font-medium hover:bg-gray-800 hover:text-white dark:hover:bg-gray-200 dark:hover:text-black" id="training-link">Training</a>
</li>
<li class="mr-1">
<a href="#help" class="bg-gray-50 dark:bg-gray-700 text-black dark:text-gray-200 py-2 px-4 rounded-t-md font-medium hover:bg-gray-800 hover:text-white dark:hover:bg-gray-200 dark:hover:text-black" id="help-link">Help</a>
</li>
</ul>
</div>
<div id="main" class="tab-pane flex flex-row flex-1">
</div>
<div class="tab-pane flex-1 overflow-auto" id="settings" style="display: none;">
</div>
<div class="tab-pane flex-1 overflow-auto" id="extensions" style="display: none;">
</div>
<div class="tab-pane flex-1 overflow-auto" id="training" style="display: none;">
</div>
<div class="tab-pane flex-1 overflow-auto" id="help" style="display: none;">
</div>
<footer class="border-t border-accent flex">
</footer>
<script src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
<script src="{{ url_for('static', filename='js/websocket.js') }}"></script>
<script src="{{ url_for('static', filename='js/chat.js') }}"></script>
<script src="{{ url_for('static', filename='js/marked.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/discussions.js') }}"></script>
<script src="{{ url_for('static', filename='js/main.js') }}"></script>
<script src="{{ url_for('static', filename='js/extensions.js') }}"></script>
<script src="{{ url_for('static', filename='js/training.js') }}"></script>
<script src="{{ url_for('static', filename='js/help.js') }}"></script>
<script src="{{ url_for('static', filename='js/settings.js') }}"></script>
<script src="{{ url_for('static', filename='js/db_export.js') }}"></script>
<script src="{{ url_for('static', filename='js/audio.js') }}"></script>
<script src="{{ url_for('static', filename='js/tabs.js') }}"></script>
<script src="{{ url_for('static', filename='js/themechecker.js') }}"></script>
<script src="{{ url_for('static', filename='js/themetoggle.js') }}"></script>
</body>
</html>

View File

@ -1,45 +0,0 @@
<div class="flex h-screen w-screen">
<div class="w-1/4 flex flex-col rounded bg-gray-50 dark:bg-gray-700 text-white h-full overflow-hidden">
<div id="action-buttons" class="flex-shrink-0 h-10 ml-1.5 mt-2 mb-4">
<button id="new-discussion-btn" class="px-4 py-4 rounded bg-gray-400 dark:bg-gray-700 hover:bg-gray-600 dark:hover:bg-gray-600">
<img src="/static/images/new_message.png" class="w-5 h-5">
</button>
<button id="reset-discussions-btn" class="px-4 py-4 rounded bg-gray-400 dark:bg-gray-700 hover:bg-gray-600 dark:hover:bg-gray-600">
<img src="/static/images/reset_db.png" class="w-5 h-5">
</button>
<button value="Export" id="export-button" class="px-4 py-4 rounded bg-gray-400 dark:bg-gray-700 hover:bg-gray-600 dark:hover:bg-gray-600">
<img src="/static/images/export_database.png" class="w-5 h-5">
</button>
<button value="Export-discussion" id="export-discussion-button" class="px-4 py-4 rounded bg-gray-400 dark:bg-gray-700 hover:bg-gray-600 dark:hover:bg-gray-600">
<img src="/static/images/export_discussion.png" class="w-5 h-5">
</button>
</div>
<div class="flex-shrink-0 p-0 ml-1.5">
<h1 class="font-bold font-large text-black dark:text-white">Discussions</h1>
</div>
<div class="flex-1 overflow-y-auto p-0">
<div id="discussions-list" class="pb-96" >
</div>
</div>
</div>
<div class="flex-1 flex flex-col overflow-hidden">
<div class="flex-shrink-0 p-4 bg-gray-50 dark:bg-gray-700 pl-7 text-black dark:text-white">
<h1 class="font-bold font-large">Chat box</h1>
</div>
<div class="flex-grow overflow-y-auto p-0 bg-gray-50 dark:bg-gray-700 rounded">
<div id="chat-window" class="pb-96">
</div>
</div>
</div>
</div>
<div class="w-full flex justify-center">
<div class="w-full flex bottom-0 fixed rounded-sm shadow shadow-white bg-gray-300 p-1 dark:bg-gray-500 flex-wrap">
<form id="chat-form" class="w-full flex-row text-white mr-15 p-15">
<textarea type="text" id="user-input" placeholder="Type your message..." class="dark:bg-gray-600 pl-1 pr-1 py-1 my-1 mr-2 text-black dark:text-white outline-none drop-shadow-sm w-full rounded-md flex-1"></textarea>
<div id="wait-animation" style="display: none;" class="lds-facebook bg-secondary my-1 mx-1 outline-none drop-shadow-sm w-full rounded-md p-2"><div></div><div></div><div></div></div>
<button id="stop-generation" style="display: none;" class="my-1 mx-1 outline-none px-4 dark:bg-gray-900 text-black dark:text-white rounded-md hover:bg-[#7ba0ea] active:bg-[#3d73e1] transition-colors ease-in-out">Stop generating</button>
<input type="submit" value="Send" id="submit-input" class="my-1 mx-1 outline-none px-4 dark:bg-gray-900 text-black dark:text-white rounded-md hover:bg-[#7ba0ea] active:bg-[#3d73e1] transition-colors ease-in-out">
</form>
</div>
</div>

View File

@ -1,71 +0,0 @@
<div class="h-full overflow-y-auto">
<form id="model-params-form" class="bg-gray-50 dark:bg-gray-700 shadow-md rounded px-8 py-8 pt-6 pb-8 mb-4 text-black dark:text-white">
<div class="mb-4 flex-row">
<label class="font-bold" for="model">Binding</label>
<select class="bg-gray-200 dark:bg-gray-700 w-96 shadow appearance-none border rounded py-2 px-3 leading-tight focus:outline-none focus:shadow-outline" id="binding" name="binding">
</select>
</div>
<div class="mb-4 flex-row">
<label class="font-bold" for="model">Model</label>
<select class="bg-gray-200 dark:bg-gray-700 w-96 shadow appearance-none border rounded py-2 px-3 leading-tight focus:outline-none focus:shadow-outline" id="model" name="model">
</select>
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="model">Personalities Languages</label>
<select class="bg-gray-200 dark:bg-gray-700 shadow appearance-none border rounded py-2 px-3 leading-tight focus:outline-none focus:shadow-outline" id="personalities_language" name="personalities_language" value="English">
</select>
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="model">Personalities Category</label>
<select class="bg-gray-200 dark:bg-gray-700 shadow appearance-none border rounded py-2 px-3 leading-tight focus:outline-none focus:shadow-outline" id="personalities_category" name="personalities_category" value="general">
</select>
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="model">Personalities</label>
<select class="bg-gray-200 dark:bg-gray-700 shadow appearance-none border rounded py-2 px-3 leading-tight focus:outline-none focus:shadow-outline" id="personalities" name="personalities" value="lollms_chatbot.yaml">
</select>
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="model">Audio in Language</label>
<select class="bg-gray-200 dark:bg-gray-700 shadow appearance-none border rounded py-2 px-3 leading-tight focus:outline-none focus:shadow-outline" id="language" name="language" value="english">
</select>
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="model">audio out Voice</label>
<select class="bg-gray-200 dark:bg-gray-700 shadow appearance-none border rounded py-2 px-3 leading-tight focus:outline-none focus:shadow-outline" id="voice" name="voice" value="english">
</select>
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="seed">Seed</label>
<input class="bg-gray-200 dark:bg-gray-700 shadow appearance-none border rounded py-2 px-3 leading-tight focus:outline-none focus:shadow-outline" id="seed" type="text" name="seed" value="0">
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="temperature" id="temperature-value">Temperature (0.1)</label>
<input class="slider-value" id="temperature" type="range" min="0" max="5" step="0.1" value="0.01" name="temperature">
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="n-predict" id="n-predict-value">N Predict (256)</label>
<input class="slider-value" id="n-predict" type="range" min="0" max="2048" step="1" value="256" name="n-predict">
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="top-k" id="top-k-value">Top K</label>
<input class="slider-value" id="top-k" type="range" min="0" max="100" step="1" value="40" name="top-k">
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="top-p" id="top-p-value">Top P</label>
<input class="slider-value" id="top-p" type="range" min="0" max="1" step="0.01" value="0.95" name="top-p">
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="repeat-penalty" id="repeat-penalty-value">Repeat penalty</label>
<input class="slider-value" id="repeat-penalty" type="range" min="0" max="2" step="0.01" value="1.3" name="repeat-penalty">
</div>
<div class="mb-4 flex-row">
<label class="font-bold mb-2" for="repeat-last-n" id="repeat-last-n-value">Repeat last N</label>
<input class="slider-value" id="repeat-last-n" type="range" min="0" max="100" step="1" value="40" name="repeat-last-n">
</div>
<div class="mb-4">
<button type="submit" id="submit-model-params" class="my-1 mx-1 outline-none px-4 bg-accent rounded-md bg-gray-200 hover:bg-gray-300 py-1 dark:bg-gray-500 dark:hover:bg-gray-300 transition-colors ease-in-out">Update parameters</button>
</div>
</form>
</div>

View File

@ -1 +0,0 @@
This section is under development. Stay tuned.

View File

@ -35,6 +35,8 @@ def run_git_pull():
def install_requirements(): def install_requirements():
try: try:
subprocess.check_call(["pip", "install", "--upgrade", "-r", "requirements.txt"]) subprocess.check_call(["pip", "install", "--upgrade", "-r", "requirements.txt"])
subprocess.check_call(["pip", "install", "--upgrade", "-e", "lollms_core"])
subprocess.check_call(["pip", "install", "--upgrade", "-r", "utilities/safe_store"])
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
print(f"Error during pip install: {e}") print(f"Error during pip install: {e}")

View File

@ -76,4 +76,4 @@ li {
ol { ol {
list-style-type: decimal; list-style-type: decimal;
margin-left: 20px; margin-left: 20px;
} }

View File

@ -1,42 +1,226 @@
<template> <template>
<div class="break-all"> <div class="break-all">
<div v-html="renderedMarkdown" class="markdown-content"></div> <div ref="mdRender" class="markdown-content">
<div v-for="(item, index) in markdownItems" :key="index">
<code-block
v-if="item.type === 'code'"
:language="item.language"
:code="item.code"
:discussion_id="discussion_id"
:message_id="message_id"
></code-block>
<div v-else v-html="item.html"></div>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import { nextTick } from 'vue'; import {nextTick, ref, onMounted, watch } from 'vue';
import feather from 'feather-icons'; import feather from 'feather-icons';
import MarkdownIt from 'markdown-it'; import MarkdownIt from 'markdown-it';
import emoji from 'markdown-it-emoji'; import emoji from 'markdown-it-emoji';
import anchor from 'markdown-it-anchor'; import anchor from 'markdown-it-anchor';
import implicitFigures from 'markdown-it-implicit-figures'; import implicitFigures from 'markdown-it-implicit-figures';
//import hljs from 'highlight.js/lib/core';
import 'highlight.js/styles/tomorrow-night-blue.css';
import 'highlight.js/styles/tokyo-night-dark.css';
import hljs from 'highlight.js/lib/common';
import 'highlight.js/styles/tomorrow-night-blue.css'; import 'highlight.js/styles/tomorrow-night-blue.css';
import 'highlight.js/styles/tokyo-night-dark.css'; import 'highlight.js/styles/tokyo-night-dark.css';
import attrs from 'markdown-it-attrs'; import attrs from 'markdown-it-attrs';
import CodeBlock from './CodeBlock.vue';
function generateUniqueId() { import hljs from 'highlight.js';
const timestamp = Date.now().toString(); function escapeHtml(unsafe) {
const randomSuffix = Math.floor(Math.random() * 1000).toString(); return unsafe
return timestamp + randomSuffix; .replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
} }
export default {
name: 'MarkdownRenderer',
props: {
markdownText: {
type: String,
required: true,
},
discussion_id: {
type: String,
required: true,
},
message_id: {
type: String,
required: true,
},
},
components: {
CodeBlock,
},
setup(props) {
const md = new MarkdownIt({
html: true,
highlight: (code, language) => {
const validLanguage = language && hljs.getLanguage(language) ? language : 'plaintext';
return hljs.highlight(validLanguage, code).value;
},
renderInline: true,
breaks: true,
})
.use(emoji)
.use(anchor)
.use(implicitFigures, {
figcaption: true,
})
.use(attrs);
const markdownItems = ref([]);
const updateMarkdown = () => {
if (props.markdownText) {
let tokens = md.parse(props.markdownText, {});
markdownItems.value = tokens.map(token => {
if (token.type === 'fence') {
return {
type: 'code',
language: escapeHtml(token.info),
code: token.content,
};
} else {
return {
type: 'html',
html: md.renderer.render([token], md.options, {}),
};
}
});
} else {
markdownItems.value = [];
}
nextTick(() => {
feather.replace();
});
};
watch(() => props.markdownText, updateMarkdown);
onMounted(updateMarkdown);
return { markdownItems };
},
};
/*
const script = document.createElement('script');
script.textContent = `
// Your inline script code here
function copyContentToClipboard(id) {
console.log("copied");
const codeElement = document.getElementById('code_' + id);
const copybtnElement = document.getElementById('copy-btn_' + id);
const copyedbtnElement = document.getElementById('copyed-btn_' + id);
copybtnElement.classList.add('hidden');
copyedbtnElement.classList.remove('hidden');
const range = document.createRange();
range.selectNode(codeElement);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
document.execCommand('copy');
window.getSelection().removeAllRanges();
}
function executeCode(id, discussion_id, message_id, lang) {
const codeElement = document.getElementById('code_' + id);
const codeExecElement = document.getElementById('code_exec_' + id);
const preExecElement = document.getElementById('pre_exec_' + id);
const code = codeElement.innerText
const json = JSON.stringify({ 'code': code, 'discussion_id': discussion_id, 'message_id':message_id, 'language': lang})
console.log(json)
fetch('http://localhost:9600/execute_code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
preExecElement.classList.remove('hidden');
codeExecElement.innerHTML = jsonData.output
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
}
function openInVsCode(id, discussion_id, message_id, lang) {
const codeElement = document.getElementById('code_' + id);
const codeExecElement = document.getElementById('code_exec_' + id);
const preExecElement = document.getElementById('pre_exec_' + id);
const code = codeElement.innerText
const json = JSON.stringify({ 'code': code, 'discussion_id': discussion_id, 'message_id':message_id, 'language': lang})
console.log(json)
fetch('http://localhost:9600/open_in_vs_code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
preExecElement.classList.remove('hidden');
codeExecElement.innerHTML = jsonData.output
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
}
function openFolder(id, discussion_id, message_id, lang) {
const codeElement = document.getElementById('code_' + id);
const codeExecElement = document.getElementById('code_exec_' + id);
const preExecElement = document.getElementById('pre_exec_' + id);
const code = codeElement.innerText
const json = JSON.stringify({ 'code': code, 'discussion_id': discussion_id, 'message_id':message_id, 'language': lang})
console.log(json)
fetch('http://localhost:9600/open_folder', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
preExecElement.classList.remove('hidden');
codeExecElement.innerHTML = jsonData.output
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
}
`;
script.async = true; // Set to true if the script should be loaded asynchronously
document.body.appendChild(script);
markdownIt.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const token = tokens[idx];
const hrefIndex = token.attrIndex('href');
if (hrefIndex >= 0) {
const hrefValue = token.attrs[hrefIndex][1];
token.attrs[hrefIndex][1] = hrefValue;
token.attrPush(['style', 'color: blue; font-weight: bold; text-decoration: underline;']);
}
return self.renderToken(tokens, idx, options);
};
const markdownIt = new MarkdownIt('commonmark', {
html: true,
xhtmlOut: true,
breaks: true,
linkify: true,
typographer: true,
highlight: (str, lang) => {
let id = generateUniqueId();
let discussion_id = 0
let message_id = 0
let btn_exec_txt = (lang=='python' || lang=='bash' || lang=='shell' || lang=='cmd' || lang=='powershell') ?'<button class="px-2 py-1 ml-10 mb-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">' + let btn_exec_txt = (lang=='python' || lang=='bash' || lang=='shell' || lang=='cmd' || lang=='powershell') ?'<button class="px-2 py-1 ml-10 mb-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">' +
'<span class="mr-1" id="exec-btn_' + '<span class="mr-1" id="exec-btn_' +
@ -145,171 +329,11 @@ const markdownIt = new MarkdownIt('commonmark', {
'</code>' + '</code>' +
'</pre>' + '</pre>' +
'</div>'; '</div>';
return codeString;
},
bulletListMarker: '-',
}).use(attrs).use(anchor).use(implicitFigures).use(emoji); // Add attrs plugin for adding attributes to elements
*/
// ... register other languages
hljs.configure({ languages: [] }); // Reset languages
hljs.configure({ languages: ['bash'] }); // Set bash as the default language
markdownIt.renderer.rules.link_open = (tokens, idx, options, env, self) => {
const token = tokens[idx];
const hrefIndex = token.attrIndex('href');
if (hrefIndex >= 0) {
const hrefValue = token.attrs[hrefIndex][1];
token.attrs[hrefIndex][1] = hrefValue;
token.attrPush(['style', 'color: blue; font-weight: bold; text-decoration: underline;']);
}
return self.renderToken(tokens, idx, options);
};
export default {
name: 'MarkdownRenderer',
props: {
markdownText: {
type: String,
required: true,
},
},
data() {
return {
renderedMarkdown: '',
isCopied: false,
};
},
mounted() {
const script = document.createElement('script');
script.textContent = `
// Your inline script code here
function copyContentToClipboard(id) {
console.log("copied");
const codeElement = document.getElementById('code_' + id);
const copybtnElement = document.getElementById('copy-btn_' + id);
const copyedbtnElement = document.getElementById('copyed-btn_' + id);
copybtnElement.classList.add('hidden');
copyedbtnElement.classList.remove('hidden');
const range = document.createRange();
range.selectNode(codeElement);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
document.execCommand('copy');
window.getSelection().removeAllRanges();
}
function executeCode(id, discussion_id, message_id, lang) {
const codeElement = document.getElementById('code_' + id);
const codeExecElement = document.getElementById('code_exec_' + id);
const preExecElement = document.getElementById('pre_exec_' + id);
const code = codeElement.innerText
const json = JSON.stringify({ 'code': code, 'discussion_id': discussion_id, 'message_id':message_id, 'language': lang})
console.log(json)
fetch('http://localhost:9600/execute_code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
preExecElement.classList.remove('hidden');
codeExecElement.innerHTML = jsonData.output
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
}
function openInVsCode(id, discussion_id, message_id, lang) {
const codeElement = document.getElementById('code_' + id);
const codeExecElement = document.getElementById('code_exec_' + id);
const preExecElement = document.getElementById('pre_exec_' + id);
const code = codeElement.innerText
const json = JSON.stringify({ 'code': code, 'discussion_id': discussion_id, 'message_id':message_id, 'language': lang})
console.log(json)
fetch('http://localhost:9600/open_in_vs_code', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
preExecElement.classList.remove('hidden');
codeExecElement.innerHTML = jsonData.output
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
}
function openFolder(id, discussion_id, message_id, lang) {
const codeElement = document.getElementById('code_' + id);
const codeExecElement = document.getElementById('code_exec_' + id);
const preExecElement = document.getElementById('pre_exec_' + id);
const code = codeElement.innerText
const json = JSON.stringify({ 'code': code, 'discussion_id': discussion_id, 'message_id':message_id, 'language': lang})
console.log(json)
fetch('http://localhost:9600/open_folder', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
preExecElement.classList.remove('hidden');
codeExecElement.innerHTML = jsonData.output
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
}
`;
script.async = true; // Set to true if the script should be loaded asynchronously
document.body.appendChild(script);
if(this.markdownText){
this.renderedMarkdown = markdownIt.render(this.markdownText);
}
else{
this.renderedMarkdown = "";
}
nextTick(() => {
feather.replace();
});
},
methods: {},
watch: {
markdownText(newText) {
this.renderedMarkdown = markdownIt.render(newText);
nextTick(() => {
feather.replace();
});
},
},
};
</script> </script>
<style>
/* Your existing styles */
</style>

122
webui.sh
View File

@ -1,122 +0,0 @@
#!/usr/bin/env bash
echo "\u001b[34m"
echo " ___ ___ ___ ___ ___ ___ "
echo " /\__\ /\ \ /\__\ /\__\ /\__\ /\ \ "
echo " /:/ / /::\ \ /:/ / /:/ / /::| | /::\ \ "
echo " /:/ / /:/\:\ \ /:/ / /:/ / /:|:| | /:/\ \ \ "
echo " /:/ / /:/ \:\ \ /:/ / /:/ / /:/|:|__|__ _\:\~\ \ \ "
echo " /:/__/ /:/__/ \:\__\ /:/__/ /:/__/ /:/ |::::\__\ /\ \:\ \ \__\ "
echo " \:\ \ \:\ \ /:/ / \:\ \ \:\ \ \/__/~~/:/ / \:\ \:\ \/__/ "
echo " \:\ \ \:\ /:/ / \:\ \ \:\ \ /:/ / \:\ \:\__\ "
echo " \:\ \ \:\/:/ / \:\ \ \:\ \ /:/ / \:\/:/ / "
echo " \:\__\ \::/ / \:\__\ \:\__\ /:/ / \::/ / "
echo " \/__/ \/__/ \/__/ \/__/ \/__/ \/__/ "
echo " By ParisNeo"
echo "\u001b[0m"
if ping -q -c 1 google.com >/dev/null 2>&1; then
echo -e "\e[32mInternet Connection working fine\e[0m"
# Install git
echo -n "Checking for Git..."
if command -v git > /dev/null 2>&1; then
echo "is installed"
else
read -p "Git is not installed. Would you like to install Git? [Y/N] " choice
if [ "$choice" = "Y" ] || [ "$choice" = "y" ]; then
echo "Installing Git..."
sudo apt update
sudo apt install -y git
else
echo "Please install Git and try again."
exit 1
fi
fi
# Check if repository exists
if [[ -d .git ]] ;then
echo Pulling latest changes
git pull
else
if [[ -d lollms-webui ]] ;then
cd lollms-webui
else
echo Cloning repository...
rem Clone the Git repository into a temporary directory
git clone https://github.com/ParisNeo/lollms-webui.git ./lollms-webui
cd lollms-webui
fi
fi
echo Pulling latest version...
git pull
# Install Python 3.10 and pip
echo -n "Checking for python3..."
if command -v python3 > /dev/null 2>&1; then
echo "is installed"
else
read -p "python3 is not installed. Would you like to install python3? [Y/N] " choice
if [ "$choice" = "Y" ] || [ "$choice" = "y" ]; then
echo "Installing python3..."
sudo apt update
sudo apt install -y python3 python3-venv
else
echo "Please install python3 and try again."
exit 1
fi
fi
# Install venv module
echo -n "Checking for venv module..."
if python3 -m venv env > /dev/null 2>&1; then
echo "is installed"
else
read -p "venv module is not available. Would you like to install it? [Y/N] " choice
if [ "$choice" = "Y" ] || [ "$choice" = "y" ]; then
echo "Installing venv module..."
sudo apt update
sudo apt install -y python3-venv
else
echo "Please install venv module and try again."
exit 1
fi
fi
# Create a new virtual environment
echo -n "Creating virtual environment..."
python3 -m venv env
if [ $? -ne 0 ]; then
echo "Failed to create virtual environment. Please check your Python installation and try again."
exit 1
else
echo "is created"
fi
fi
# Activate the virtual environment
echo -n "Activating virtual environment..."
source env/bin/activate
echo "is active"
# Install the required packages
echo "Installing requirements..."
python3 -m pip install pip --upgrade
python3 -m pip install --upgrade -r requirements.txt
if [ $? -ne 0 ]; then
echo "Failed to install required packages. Please check your internet connection and try again."
exit 1
fi
# Cleanup
if [ -d "./tmp" ]; then
rm -rf "./tmp"
echo "Cleaning tmp folder"
fi
# Launch the Python application
python app.py "$@"

@ -1 +1 @@
Subproject commit ecec471d269ff305b7fb1700d506ce8a63ba53cd Subproject commit 7d397574d4de60b37beff4474184664ae7ce40ec