@@ -85,8 +85,9 @@ export const chatMessagesApi = {
})
},
- reconnectMessageStream: (chatUid: string, messageUid: string, offset: number, token: string, signal?: AbortSignal) => {
- const url = `${getApiUrl() + '/api'}/chats/${chatUid}/messages/${messageUid}/stream?offset=${offset}`
+ reconnectMessageStream: (chatUid: string, offset: number, token: string, signal?: AbortSignal) => {
+ const baseUrl = `${getApiUrl() + '/api'}/chats/${chatUid}/messages/stream`
+ const url = offset > 0 ? `${baseUrl}?offset=${offset}` : baseUrl
return fetch(url, {
method: 'GET',
@@ -1,3 +1,37 @@
+.markdown {
+ max-width: 100%;
+ overflow-wrap: anywhere;
+ word-break: break-word;
+
+ p,
+ li,
+ h1,
+ h2,
+ h3,
+ h4,
+ h5,
+ h6,
+ blockquote {
+ overflow-wrap: anywhere;
+ word-break: break-word;
+ }
+
+ table {
+ display: block;
+ max-width: 100%;
+ overflow-x: auto;
+ }
+
+ pre {
+ max-width: 100%;
+ white-space: pre-wrap;
+ word-break: break-word;
+ overflow-x: hidden;
+ }
+}
+
.inlineCode {
border-radius: 15px;
+ white-space: pre-wrap;
+ word-break: break-word;
}
@@ -14,7 +14,7 @@ export const Markdown = ({ content, id = 'markdown'}: IProps) => {
const LazyCode = dynamic(() => import('#/widgets/chat-gpt-field/ui/code'))
return (
-
+
message.uid === TEMP_USER_MESSAGE_UID || message.uid === pendingUid
+ )
+
+ if (options.isReconnect && !hasPlaceholder) {
+ return ensureModelMessageForStream(prev, messageUuid, modelType, runtime.modelContent)
+ }
+
return prev.map((message) => {
if (message.uid === TEMP_USER_MESSAGE_UID) {
return { ...message, uid: messageUuid }
@@ -358,10 +362,12 @@ export function useChatModel(
},
})
+ const hasActiveSession = readChatStreamSession(currentChat) !== null
+
return {
- shouldReconnect: runtime.streamFailed && runtime.hasStreamEvents,
+ shouldReconnect: runtime.streamFailed && (runtime.hasStreamEvents || hasActiveSession),
streamFailed: runtime.streamFailed,
- missingStart: !runtime.hasStreamEvents && !options.isReconnect && !inputMessageUuidRef.current,
+ missingStart: !runtime.hasStreamEvents && !options.isReconnect && !hasActiveSession,
}
},
[currentChat, modelType, persistStreamSession]
@@ -406,7 +412,6 @@ export function useChatModel(
try {
const response = await chatMessagesApi.reconnectMessageStream(
chatUid,
- inputMessageUuid,
streamOffset,
data.access,
abortController.signal
@@ -469,16 +474,21 @@ export function useChatModel(
const tryReconnectOnLoad = useCallback(
async (chatUid: string, loadedMessages: Message[]) => {
const session = readChatStreamSession(chatUid)
- const reconnectTarget = session ?? detectInProgressStream(loadedMessages)
+ const detected = detectInProgressStream(loadedMessages)
- if (!reconnectTarget) {
+ if (!session && !detected) {
return
}
+ const inputMessageUuid =
+ session?.inputMessageUuid && session.inputMessageUuid !== STREAMING_PENDING_UID
+ ? session.inputMessageUuid
+ : (detected?.inputMessageUuid ?? session?.inputMessageUuid ?? STREAMING_PENDING_UID)
+
await reconnectToStream(
chatUid,
- reconnectTarget.inputMessageUuid,
- reconnectTarget.lastOffset,
+ inputMessageUuid,
+ session?.lastOffset ?? detected?.lastOffset ?? 0,
loadedMessages,
session?.modelContent
)
@@ -635,10 +645,17 @@ export function useChatModel(
createStreamingModelMessage(STREAMING_PENDING_UID, streamCreatedAtRef.current, modelType),
])
+ writeChatStreamSession(currentChat, {
+ inputMessageUuid: STREAMING_PENDING_UID,
+ lastOffset: 0,
+ modelContent: getWaitingForModelContent(modelType),
+ })
+
try {
const response = await chatMessagesApi.sendMessageStream(currentChat, requestBody, data.access, abortController.signal)
if (!response.ok) {
+ clearChatStreamSession(currentChat)
markOptimisticUserMessageFailed()
setMessages((prev) => removeStreamingModelMessage(prev))
showMessage(await parseStreamErrorResponse(response))
@@ -646,6 +663,7 @@ export function useChatModel(
}
if (!response.body) {
+ clearChatStreamSession(currentChat)
markOptimisticUserMessageFailed()
setMessages((prev) => removeStreamingModelMessage(prev))
showMessage('Пустой ответ сервера')
@@ -654,10 +672,13 @@ export function useChatModel(
const result = await processMessageStream(response)
- if (result.shouldReconnect && inputMessageUuidRef.current) {
+ if (result.shouldReconnect) {
+ const inputUuid =
+ inputMessageUuidRef.current ?? readChatStreamSession(currentChat)?.inputMessageUuid ?? STREAMING_PENDING_UID
+
await reconnectToStream(
currentChat,
- inputMessageUuidRef.current,
+ inputUuid,
streamRuntimeRef.current.lastOffset,
undefined,
streamRuntimeRef.current.modelContent,
@@ -667,6 +688,7 @@ export function useChatModel(
}
if (result.missingStart) {
+ clearChatStreamSession(currentChat)
markOptimisticUserMessageFailed()
setMessages((prev) => removeStreamingModelMessage(prev))
showMessage('Непредвиденная ошибка, попробуйте еще раз')
@@ -676,19 +698,17 @@ export function useChatModel(
return
}
- const inputUuid = inputMessageUuidRef.current
- const runtime = streamRuntimeRef.current
-
- if (inputUuid && runtime.hasStreamEvents) {
- persistStreamSession(currentChat, inputUuid)
- await reconnectToStream(currentChat, inputUuid, runtime.lastOffset, undefined, runtime.modelContent, {
+ const session = readChatStreamSession(currentChat)
+ if (session) {
+ const inputUuid = inputMessageUuidRef.current ?? session.inputMessageUuid
+ await reconnectToStream(currentChat, inputUuid, session.lastOffset, undefined, session.modelContent, {
silent: true,
})
return
}
- markOptimisticUserMessageFailed(inputUuid)
- setMessages((prev) => removeStreamingModelMessage(prev, inputUuid))
+ markOptimisticUserMessageFailed()
+ setMessages((prev) => removeStreamingModelMessage(prev))
showMessage('Непредвиденная ошибка, попробуйте еще раз')
} finally {
isSendingRef.current = false
@@ -77,9 +77,10 @@ export function BotMessage(props: any) {
@@ -111,7 +112,7 @@ export function BotMessage(props: any) {
})}
-
+
{
if (props.message.file) {
@@ -120,7 +121,12 @@ export function BotMessage(props: any) {
}}
className='smallScroll'
sx={{
+ flex: 1,
+ minWidth: 0,
overflowY: 'auto',
+ overflowX: 'hidden',
+ overflowWrap: 'anywhere',
+ wordBreak: 'break-word',
position: 'relative',
padding: '15px 23px',
border: `1px solid #303035`,
@@ -153,7 +159,7 @@ export function BotMessage(props: any) {
)}
-
+