-
Notifications
You must be signed in to change notification settings - Fork 11.8k
server : (webui) revamp the input area, plus many small UI improvements #13365
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
Conversation
CC @gary149 if you have some suggestions :) |
Could you please label the conversation with the model name, like |
Yes I thought about this but forgot to note it down, will do it now |
throw std::runtime_error("Failed to parse messages: " + std::string(e.what()) + "; messages = " + messages.dump(2)); | ||
// @ngxson : disable otherwise it's bloating the API response | ||
// printf("%s\n", std::string("; messages = ") + messages.dump(2)); | ||
throw std::runtime_error("Failed to parse messages: " + std::string(e.what())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small note @ochafik , we should never reflect user input via the error message, as it usually comes with security risks. In this case, it's not a security risk, but it's a bit inconvenient to display the error in the UI
If you want to print the input for debugging, consider using LOG_DBG
<b>Server Info</b> | ||
<p> | ||
<b>Model</b>: {serverProps?.model_path?.split(/(\\|\/)/).pop()} | ||
<br /> | ||
<b>Build</b>: {serverProps?.build_info} | ||
<br /> | ||
</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to myself: maybe display extra info, like server capabilities (speculative, FIM, multimodal, etc)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving some comments to make reviewing easier
// WARN: vibe code below | ||
// This code is a heuristic to determine if a string is likely not binary. | ||
// It is necessary because input file can have various mime types which we don't have time to investigate. | ||
// For example, a python file can be text/plain, application/x-python, etc. | ||
export function isLikelyNotBinary(str: string): boolean { | ||
const options = { | ||
prefixLength: 1024 * 10, // Check the first 10KB of the string | ||
suspiciousCharThresholdRatio: 0.15, // Allow up to 15% suspicious chars | ||
maxAbsoluteNullBytes: 2, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each file extension like .py, .c, .cpp, .sh, .bat, etc has their own set of mime type which is very difficult to keep track. Therefore, this function was added.
It should also work with unicode text. I tested with:
model_path: string; | ||
n_ctx: number; | ||
has_multimodal: boolean; | ||
// TODO: support params |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a next PR, we can use the server's default params
to override the settings, this will address #13277
export function useChatScroll(msgListRef: React.RefObject<HTMLDivElement>) { | ||
useEffect(() => { | ||
if (!msgListRef.current) return; | ||
|
||
const resizeObserver = new ResizeObserver((_) => { | ||
scrollToBottomThrottled(true, 10); | ||
}); | ||
|
||
resizeObserver.observe(msgListRef.current); | ||
return () => { | ||
resizeObserver.disconnect(); | ||
}; | ||
}, [msgListRef]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This replaces the old logic where scrollToBottom
gets triggered every time a new token is received. The new approach relies on ResizeObserver
, which is a browser's API to observe if a HTML element changes its size. This should now cover the case where browser window is resized
} else if (extra.type === 'textFile') { | ||
contentArr.push({ | ||
type: 'text', | ||
text: `File: ${extra.name}\nContent:\n\n${extra.content}`, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is now the input file will be formatted upon sending to server. The file name will be preserved
Looks great now. |
* origin/master: (39 commits) server : vision support via libmtmd (ggml-org#12898) sycl : implementation of reordered Q4_0 MMVQ for Intel GPUs (ggml-org#12858) metal : optimize MoE for large batches (ggml-org#13388) CUDA: FA support for Deepseek (Ampere or newer) (ggml-org#13306) llama : do not crash if there is no CPU backend (ggml-org#13395) CUDA: fix crash on large batch size for MoE models (ggml-org#13384) imatrix : Add --parse-special for enabling parsing of special tokens in imatrix calculation (ggml-org#13389) llama-run: add support for downloading models from ModelScope (ggml-org#13370) mtmd : fix batch_view for m-rope (ggml-org#13397) llama : one-off chat template fix for Mistral-Small-2503 (ggml-org#13398) rpc : add rpc_msg_set_tensor_hash_req (ggml-org#13353) vulkan: Allow up to 4096 elements for mul_mat_id row_ids (ggml-org#13326) server : (webui) rename has_multimodal --> modalities (ggml-org#13393) ci : limit write permission to only the release step + fixes (ggml-org#13392) mtmd : Expose helper_decode_image_chunk (ggml-org#13366) server : (webui) fix a very small misalignment (ggml-org#13387) server : (webui) revamp the input area, plus many small UI improvements (ggml-org#13365) convert : support rope_scaling type and rope_type (ggml-org#13349) mtmd : fix the calculation of n_tokens for smolvlm (ggml-org#13381) context : allow cache-less context for embeddings (ggml-org#13108) ...
@ngxson my vertical 3 points icon is missing from the sidebar. |
I found the reason behind that. After I turned off the fullscreen, the icon showed. Thank you for your help. |
Many small UI/UX improvements that I wanted to have, but now finally have time to do.
TODO:
txt
file, for example.c
,.py
, etcOverall UI:
Detail improvements
(1) Remove background color in assistant message, to make it easier to read
(2) Improve the input UI/UX
(3) Allow uploading files (plus, prepare the code to upload image - enable it once the API support image input via #12898 )
Drap-and-drop file to input area is supported
TODO in a next PR: allow ctrl+v long content, the long content will be converted to file automatically
(4) Use
HeroIcons
everywhere + more consistent icons(5) Move conversation options menu to sidebar, add "rename" option
(6) Improve "thought process" display
Note: the default assistant message is removed, this is because more and more models not requiring system message