Skip to content

Commit

Permalink
Merge pull request #40 from SkywardAI/function-improve
Browse files Browse the repository at this point in the history
v0.1.6 bug fix & new setting page & input validation
  • Loading branch information
cbh778899 authored Jul 15, 2024
2 parents ee25509 + d3dd5f6 commit f74cda8
Show file tree
Hide file tree
Showing 23 changed files with 538 additions and 307 deletions.
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

0 comments on commit f74cda8

Please sign in to comment.