feat(message): add error tips
This commit is contained in:
parent
16c68dcdcb
commit
5a0927393d
@ -210,6 +210,10 @@ const resources = {
|
|||||||
'keep_alive_time.title': 'Keep Alive Time',
|
'keep_alive_time.title': 'Keep Alive Time',
|
||||||
'keep_alive_time.placeholder': 'Minutes',
|
'keep_alive_time.placeholder': 'Minutes',
|
||||||
'keep_alive_time.description': 'The time in minutes to keep the connection alive, default is 5 minutes.'
|
'keep_alive_time.description': 'The time in minutes to keep the connection alive, default is 5 minutes.'
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
'chat.response':
|
||||||
|
'Something went wrong. Please check your API key in settings > providers, or check your proxy in Settings > General > Proxy'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -421,6 +425,9 @@ const resources = {
|
|||||||
'keep_alive_time.title': '保持活跃时间',
|
'keep_alive_time.title': '保持活跃时间',
|
||||||
'keep_alive_time.placeholder': '分钟',
|
'keep_alive_time.placeholder': '分钟',
|
||||||
'keep_alive_time.description': '对话后模型在内存中保持的时间(默认:5分钟)'
|
'keep_alive_time.description': '对话后模型在内存中保持的时间(默认:5分钟)'
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
'chat.response': '出错了,这通常是由于没有正确配置 API 密钥或代理导致的, 请前往设置 > 模型提供商中配置 API 密钥'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import { useRuntime } from '@renderer/hooks/useStore'
|
|||||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
|
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
|
||||||
import { Message, Model } from '@renderer/types'
|
import { Message, Model } from '@renderer/types'
|
||||||
import { firstLetter, removeLeadingEmoji } from '@renderer/utils'
|
import { firstLetter, removeLeadingEmoji } from '@renderer/utils'
|
||||||
import { Avatar, Dropdown, Popconfirm, Tooltip } from 'antd'
|
import { Alert, Avatar, Dropdown, Popconfirm, Tooltip } from 'antd'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { upperFirst } from 'lodash'
|
import { upperFirst } from 'lodash'
|
||||||
import { FC, memo, useCallback, useMemo, useState } from 'react'
|
import { FC, memo, useCallback, useMemo, useState } from 'react'
|
||||||
@ -95,6 +95,29 @@ const MessageItem: FC<Props> = ({ message, index, showMenu, onDeleteMessage }) =
|
|||||||
[t, message]
|
[t, message]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const MessageItem = useCallback(() => {
|
||||||
|
if (message.status === 'sending') {
|
||||||
|
return (
|
||||||
|
<MessageContentLoading>
|
||||||
|
<SyncOutlined spin size={24} />
|
||||||
|
</MessageContentLoading>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.status === 'error') {
|
||||||
|
return (
|
||||||
|
<Alert
|
||||||
|
message={t('error.chat.response')}
|
||||||
|
description={<Markdown message={message} />}
|
||||||
|
type="error"
|
||||||
|
style={{ marginBottom: 15 }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Markdown message={message} />
|
||||||
|
}, [message])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MessageContainer key={message.id} className="message" style={{ border: messageBorder }}>
|
<MessageContainer key={message.id} className="message" style={{ border: messageBorder }}>
|
||||||
<MessageHeader>
|
<MessageHeader>
|
||||||
@ -113,12 +136,7 @@ const MessageItem: FC<Props> = ({ message, index, showMenu, onDeleteMessage }) =
|
|||||||
</AvatarWrapper>
|
</AvatarWrapper>
|
||||||
</MessageHeader>
|
</MessageHeader>
|
||||||
<MessageContent style={{ fontFamily }}>
|
<MessageContent style={{ fontFamily }}>
|
||||||
{message.status === 'sending' && (
|
<MessageItem />
|
||||||
<MessageContentLoading>
|
|
||||||
<SyncOutlined spin size={24} />
|
|
||||||
</MessageContentLoading>
|
|
||||||
)}
|
|
||||||
{message.status !== 'sending' && <Markdown message={message} />}
|
|
||||||
{message.usage && !generating && (
|
{message.usage && !generating && (
|
||||||
<MessageMetadata>
|
<MessageMetadata>
|
||||||
Tokens: {message.usage.total_tokens} | ↑{message.usage.prompt_tokens}↓{message.usage.completion_tokens}
|
Tokens: {message.usage.total_tokens} | ↑{message.usage.prompt_tokens}↓{message.usage.completion_tokens}
|
||||||
|
|||||||
@ -50,6 +50,16 @@ export async function fetchChatCompletion({
|
|||||||
|
|
||||||
onResponse({ ...message })
|
onResponse({ ...message })
|
||||||
|
|
||||||
|
// Handle paused state
|
||||||
|
let paused = false
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
if (window.keyv.get(EVENT_NAMES.CHAT_COMPLETION_PAUSED)) {
|
||||||
|
paused = true
|
||||||
|
onResponse({ ...message, status: 'paused' })
|
||||||
|
clearInterval(timer)
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await providerSdk.completions(filterAtMessages(messages), assistant, ({ text, usage }) => {
|
await providerSdk.completions(filterAtMessages(messages), assistant, ({ text, usage }) => {
|
||||||
message.content = message.content + text || ''
|
message.content = message.content + text || ''
|
||||||
@ -58,10 +68,17 @@ export async function fetchChatCompletion({
|
|||||||
})
|
})
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
message.content = `Error: ${error.message}`
|
message.content = `Error: ${error.message}`
|
||||||
|
message.status = 'error'
|
||||||
|
}
|
||||||
|
|
||||||
|
timer && clearInterval(timer)
|
||||||
|
|
||||||
|
if (paused) {
|
||||||
|
return message
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update message status
|
// Update message status
|
||||||
message.status = window.keyv.get(EVENT_NAMES.CHAT_COMPLETION_PAUSED) ? 'paused' : 'success'
|
message.status = window.keyv.get(EVENT_NAMES.CHAT_COMPLETION_PAUSED) ? 'paused' : message.status
|
||||||
|
|
||||||
// Emit chat completion event
|
// Emit chat completion event
|
||||||
EventEmitter.emit(EVENT_NAMES.AI_CHAT_COMPLETION, message)
|
EventEmitter.emit(EVENT_NAMES.AI_CHAT_COMPLETION, message)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user