Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.1.6 bug fix #40

Merged
merged 18 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions components/account-page/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import capitalizeFirstLetter from "../../tools/capitalizeFirstLetter.js";
import getSVG from "../../tools/svgs.js";
import showMessage from "../../tools/message.js";
import createDialog from '../../tools/dialog.js';
import { email_not_valid, password_not_valid, username_not_valid, validateEmail, validatePassword, validateUsername } from '../../tools/validators.js';

let input_details_main = null, init = false, toggleDialog;
let current_user = {}, isRegister = false, user_info_saved = localStorage.getItem('saved-user-login-info');
Expand All @@ -11,8 +12,8 @@ if(user_info_saved) user_info_saved = JSON.parse(user_info_saved);
const {
register, login, logout, updateUserInfo
} = useUser(user=>{
if(!input_details_main) return;
current_user = user;
if(!input_details_main) return;
createInputDetailsPage();
});

Expand Down Expand Up @@ -127,11 +128,18 @@ function submitDetails(evt) {
const repeat_new_password = evt.target['repeat-new-password'].value;
const submit_values = {}
if(email && email !== current_user.email) {
if(!validateEmail(email)) {
showMessage(email_not_valid, { type: "error" })
return;
}
submit_values.email = email;
}
if(new_password) {
if(repeat_new_password !== new_password) {
showMessage("Passwords are not same!", { type: 'err' })
if(!validatePassword(new_password)) {
showMessage(password_not_valid, { type: 'err' })
return;
} else if(repeat_new_password !== new_password) {
showMessage("Passwords are not same!", { type: 'err' })
return;
}
submit_values.password = new_password;
Expand All @@ -152,6 +160,17 @@ function submitDetails(evt) {
const keep_login = evt.target['keep-login'].checked;
if(isRegister) {
const email = evt.target.email.value;
if(!validateUsername(username)) {
showMessage(username_not_valid, { type: 'err' })
return;
} else if(!validateEmail(email)) {
showMessage(email_not_valid, { type: 'err' })
return;
} else if(!validatePassword(password)) {
showMessage(password_not_valid, { type: 'err' })
return;
}

const repeat_password = evt.target['repeat-password'].value;

if(password !== repeat_password) {
Expand Down
86 changes: 57 additions & 29 deletions components/chat-page/chatMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,21 @@ import showMessage from "../../tools/message.js";
import request from "../../tools/request.js";
import getSVG from "../../tools/svgs.js";

let conversation = {}, model_settings = {},
let conversation = {pending: false}, model_settings = {},
main_elem, toggle_expand,
stream_response=true;

let abort_controller;

const {
componetDismount: conversationDismount,
componentReMount: conversationReMount,
togglePending,
togglePending, rename,
sendMessage:appendConversationMessage
} = useConversation(c=>{
conversation.pending = c.pending;
const submit_icon = document.querySelector('#submit-chat .send svg.submit-icon');
submit_icon && submit_icon.classList.toggle('pending', conversation.pending)
const submit_chat_form = document.getElementById('submit-chat')
submit_chat_form && submit_chat_form.classList.toggle('pending', conversation.pending);
if(c.id === conversation.id) return;
conversation = c;
if(!conversation.id) {
Expand All @@ -43,7 +45,7 @@ const {
model_settings = s;
})

const { getHistory, updateHistoryName } = useHistory();
const { getHistory } = useHistory();

export default function createChatMain(main, toggleExpand, openModelSetting) {
main.insertAdjacentHTML('beforeend', `
Expand Down Expand Up @@ -102,9 +104,9 @@ export default function createChatMain(main, toggleExpand, openModelSetting) {
function buildForm() {
const submit_chat = document.getElementById('submit-chat')
submit_chat.innerHTML = `
<div class='send'>
<input type='submit' class='submit-btn clickable'>
${getSVG('send', 'submit-icon')}
<div class='right-button'>
<input type='submit' class='btn clickable'>
${getSVG('send', 'icon send')}
</div>`;

const input = document.createElement('input');
Expand All @@ -114,7 +116,15 @@ function buildForm() {

submit_chat.insertAdjacentElement("afterbegin", input);
submit_chat.clientHeight;


const abortMessage = document.createElement('div');
abortMessage.className = 'right-button abort-message clickable'
abortMessage.onclick = () => {
conversation.pending && abort_controller.abort();
}
abortMessage.innerHTML = getSVG('stop-circle-fill', 'icon');
submit_chat.appendChild(abortMessage);

if(!conversation.history.length) {
toggle_expand();
input.focus();
Expand All @@ -125,18 +135,24 @@ function submitContent(evt) {
evt.preventDefault();
if(conversation.pending) {
showMessage(
"Please wait until assistant finished response.",
"Please wait until assistant finished response or abort manually.",
{ type: 'warn' }
)
return;
}

const content = evt.target['send-content'].value;
content && (
if(content) {
stream_response ?
sendMessageStream(content) :
sendMessageWaiting(content)
)
} else {
showMessage(
"Message is empty, feel free to ask anything!",
{ type: 'warn' }
)
return;
}
evt.target['send-content'].value = ''
}

Expand All @@ -145,8 +161,7 @@ async function sendMessage(message, send) {
if(!conversation.history.length) {
main_elem.innerHTML = ''
const message_len = message.length;
updateHistoryName(conversation.id,
`${message.substring(0, 25)}${message_len > 25 ? '...' : ''}`)
await rename(`${message.substring(0, 25)}${message_len > 25 ? '...' : ''}`)
}
main_elem.appendChild(createBlock('user', message)[0]);
main_elem.scrollTo({
Expand All @@ -156,21 +171,34 @@ async function sendMessage(message, send) {
const [bot_answer, updateMessage] = createBlock('assistant');
main_elem.appendChild(bot_answer);

const response = await request('chat', {
method: 'POST',
body: {
sessionUuid: conversation.id || "uuid",
message, ...model_settings
}
}, true)

const content = await send(response, updateMessage);
togglePending();

appendConversationMessage([
{ role: 'user', message },
{ role: 'assistant', message: content}
], conversation.id)
let content = ''
try {
abort_controller = new AbortController();
const response = await request('chat', {
method: 'POST',
signal: abort_controller.signal,
body: {
sessionUuid: conversation.id || "uuid",
message, ...model_settings
}
}, true)

await send(response, msg=>{
content = msg;
updateMessage(msg);
});
} catch(error) {
error;
if(content) content+=' ...'
content += '(Message Abroted)'
updateMessage(content)
} finally {
appendConversationMessage([
{ role: 'user', message },
{ role: 'assistant', message: content}
], conversation.id);
togglePending();
}
}

function sendMessageWaiting(msg) {
Expand Down
6 changes: 4 additions & 2 deletions components/chat-page/history.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import useConversation from "../../global/useConversation.js";
import useHistory from "../../global/useHistory.js";

let history = [], history_elem = null, last_selected_id;
let history = [], history_elem = null, last_selected_id=null;

const { componetDismount:historyDismount, componentReMount: historyRemount } = useHistory(h=>{
history = structuredClone(h);
Expand All @@ -25,6 +25,8 @@ export default function createChatHistory(main) {
history_elem.id = 'chat-history';
main.insertAdjacentElement('beforeend', history_elem);

last_selected_id = null;

// re-mount update listeners
historyRemount();
conversationRemount();
Expand Down Expand Up @@ -62,7 +64,7 @@ function updateHistoryList() {
<div class='datetime'>${createdAt}</div>`

ticket.onclick = () => {
selectConversation(id);
selectConversation(id, name);
}

tickets_list.appendChild(ticket)
Expand Down
5 changes: 2 additions & 3 deletions components/chat-page/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import createDialog from "../../tools/dialog.js";
import createChatMain from "./chatMain.js";
import createChatHistory from "./history.js";
import createModelSettings from "./modelSettings.js";
import createChatSettingsPage from "./settings.js";

const [settings_main, { toggleModal }] = createDialog();
document.body.appendChild(settings_main)

export default function createChatPage() {
const chatPage = document.createElement('div');
Expand All @@ -20,7 +19,7 @@ export default function createChatPage() {

dismount_components.push(createChatHistory(chatPage));
dismount_components.push(createChatMain(chatPage, toggleExpand, toggleModal));
dismount_components.push(createModelSettings(settings_main));
createChatSettingsPage(settings_main);

return () => {
dismount_components.forEach(e=>e());
Expand Down
44 changes: 44 additions & 0 deletions components/chat-page/model-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import useModelSettings from "../../global/useModelSettings.js";
import rangeSettingSection from "./range-setting-section.js";

let settings = {};

const {
updateSettings:updateModelSettings, setToDefault
} = useModelSettings(s=>settings = s);

const fields = {
temperature: { title: 'Temperature', valueRange: { min: 0, max: 2, is_100_times: true } },
top_k: { title: 'Top-K', valueRange: { min: 0, max: 40 } },
top_p: { title: 'Top-P', valueRange: { min: 0, max: 0.9, is_100_times: true } },
n_predict: { title: 'N-Predict', valueRange: { min: 128, max: 512 } }
}

export default function createModelSettings(main) {
const model_settings = document.createElement('div');

model_settings.innerHTML = `
<div class='title'>Adjust Model Settings</div>
<div class='sub-title'>Settings will be saved automatically</div>
`

for(const key in fields) {
const { title, valueRange } = fields[key];
const [component, setter] = rangeSettingSection(
title, valueRange,
() => { setToDefault(key) && loadSettings() },
value=>updateModelSettings(key, value)
)
model_settings.appendChild(component);
fields[key].setValue = setter;
}

main.appendChild(model_settings);
loadSettings();
}

function loadSettings() {
for(const key in fields) {
fields[key].setValue(settings[key]);
}
}
54 changes: 0 additions & 54 deletions components/chat-page/modelSettings.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import getSVG from "../../tools/svgs.js";

export default function settingSection(title, valueRange, setToDefault, updateSetting) {
export default function rangeSettingSection(title, valueRange, setToDefault, updateSetting) {

const { max, min, from_range, to_range } = rangeValueConverter(valueRange)

Expand Down
Loading
Loading