refactor(playground): extract non-stream response handling

- move chat completion response choice handling into message streaming utilities
- keep the chat handler focused on request lifecycle and error routing
This commit is contained in:
QuentinHsu
2026-05-30 11:04:59 +08:00
parent 378eed2bd4
commit 6ba23572b2
2 changed files with 30 additions and 6 deletions
@@ -26,8 +26,9 @@ import {
updateAssistantMessageWithError,
updateLastAssistantMessage,
parseRequestErrorDetails,
applyChatCompletionChoice,
applyChatCompletionResponse,
completeAssistantMessage,
hasChatCompletionChoice,
isAssistantMessageFinal,
isAssistantMessagePending,
} from '../lib'
@@ -137,16 +138,20 @@ export function useChatHandler({
)
if (abortController.signal.aborted) return
const choice = response.choices?.[0]
if (!choice) {
if (!hasChatCompletionChoice(response)) {
handleStreamError(ERROR_MESSAGES.API_REQUEST_ERROR)
return
}
onMessageUpdate((prev) =>
updateLastAssistantMessage(prev, (message) =>
applyChatCompletionChoice(message, choice)
)
updateLastAssistantMessage(prev, (message) => {
const updatedMessage = applyChatCompletionResponse(
message,
response
)
return updatedMessage ?? message
})
)
} catch (error: unknown) {
if (abortController.signal.aborted) return
@@ -125,6 +125,12 @@ export function isAssistantMessagePending(message: Message): boolean {
type ChatCompletionChoice = ChatCompletionResponse['choices'][number]
export function hasChatCompletionChoice(
response: ChatCompletionResponse
): boolean {
return Boolean(response.choices?.[0])
}
export function applyChatCompletionChoice(
message: Message,
choice: ChatCompletionChoice
@@ -138,6 +144,19 @@ export function applyChatCompletionChoice(
}
}
export function applyChatCompletionResponse(
message: Message,
response: ChatCompletionResponse
): Message | null {
const choice = response.choices?.[0]
if (!choice) {
return null
}
return applyChatCompletionChoice(message, choice)
}
/**
* Sanitize messages loaded from storage.
* Converts stuck loading/streaming messages to stable state.