ui: model status and load progress via /models/sse feed (#24878)

* ui: model status and load progress via /models/sse feed

* ui: centralize SSE wire-format delimiters into shared constants for the chat and /models/sse parsers

* ui: type /models/sse event names as a ServerModelsSseEventType enum

Address review from allozaur
This commit is contained in:
Pascal
2026-06-22 15:55:30 +02:00
committed by GitHub
parent f8cc15f163
commit 099b579acb
17 changed files with 466 additions and 57 deletions
+9 -7
View File
@@ -10,7 +10,10 @@ import {
SETTINGS_KEYS,
API_CHAT,
API_SLOTS,
CONTROL_ACTION
CONTROL_ACTION,
SSE_LINE_SEPARATOR,
SSE_DATA_PREFIX,
SSE_DONE_MARKER
} from '$lib/constants';
import {
AttachmentType,
@@ -18,8 +21,7 @@ import {
FileTypeAudio,
MessageRole,
MimeTypeAudio,
ReasoningFormat,
UrlProtocol
ReasoningFormat
} from '$lib/enums';
import type {
ApiChatMessageContentPart,
@@ -642,15 +644,15 @@ export class ChatService {
if (abortSignal?.aborted) break;
chunk += decoder.decode(value, { stream: true });
const lines = chunk.split('\n');
const lines = chunk.split(SSE_LINE_SEPARATOR);
chunk = lines.pop() || '';
for (const line of lines) {
if (abortSignal?.aborted) break;
if (line.startsWith(UrlProtocol.DATA)) {
const data = line.slice(6);
if (data === '[DONE]') {
if (line.startsWith(SSE_DATA_PREFIX)) {
const data = line.slice(SSE_DATA_PREFIX.length).trim();
if (data === SSE_DONE_MARKER) {
streamFinished = true;
continue;