webui: add setting for first-line chat titles (#21797)

* webui: add setting for first-line chat titles

Add an opt-in setting (`titleGenerationUseFirstLine`) to use the first
non-empty line of a prompt as the generated conversation title.

Previously, the complete multi-line prompt was being used, which created
long titles for complex queries. Coupled with
"Ask for confirmation before changing conversation title", the dialog
would overflow.

* Update tools/server/webui/src/lib/utils/text.ts

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

* Update tools/server/webui/src/lib/utils/text.ts

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>

* webui: Run build to update the bundle

As requested in:
https://github.com/ggml-org/llama.cpp/pull/21797#pullrequestreview-4094935065

* webui: Fix missing import for NEWLINE_SEPARATOR

---------

Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>
This commit is contained in:
Rohan Jain
2026-04-13 13:00:46 +05:30
committed by GitHub
parent 227ed28e12
commit 974c8c94cc
9 changed files with 350 additions and 305 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ export {
// File preview utilities
export { getFileTypeLabel } from './file-preview';
export { getPreviewText } from './text';
export { getPreviewText, generateConversationTitle } from './text';
// File type utilities
export {
+15
View File
@@ -1,3 +1,5 @@
import { NEWLINE_SEPARATOR } from '$lib/constants';
/**
* Returns a shortened preview of the provided content capped at the given length.
* Appends an ellipsis when the content exceeds the maximum.
@@ -5,3 +7,16 @@
export function getPreviewText(content: string, max = 150): string {
return content.length > max ? content.slice(0, max) + '...' : content;
}
/**
* Generates a single-line title from a potentially multi-line prompt.
* Uses the first non-empty line if `useFirstLine` is true.
*/
export function generateConversationTitle(content: string, useFirstLine: boolean = false): string {
if (useFirstLine) {
const firstLine = content.split(NEWLINE_SEPARATOR).find((line) => line.trim().length > 0);
return firstLine ? firstLine.trim() : content.trim();
}
return content.trim();
}