service 修改 Redis 存储 KV
This commit is contained in:
@@ -50,8 +50,8 @@ export default {
|
||||
showRawText: 'Show as raw text',
|
||||
sourceSemantic: 'Semantic Match',
|
||||
sourceLlm: 'LLM Output',
|
||||
promptTokens: 'Prompt {count} tokens',
|
||||
completionTokens: 'Completion {count} tokens',
|
||||
inputTokens: 'Input {count}',
|
||||
outputTokens: 'Output {count}',
|
||||
sessionTokens: 'Session {count} tokens',
|
||||
},
|
||||
setting: {
|
||||
|
||||
@@ -50,8 +50,8 @@ export default {
|
||||
showRawText: '显示原文',
|
||||
sourceSemantic: '语义匹配',
|
||||
sourceLlm: '大模型输出',
|
||||
promptTokens: '问题 {count} tokens',
|
||||
completionTokens: '回答 {count} tokens',
|
||||
inputTokens: 'Input {count}',
|
||||
outputTokens: 'Output {count}',
|
||||
sessionTokens: '本轮消耗 {count} tokens',
|
||||
},
|
||||
setting: {
|
||||
|
||||
@@ -50,8 +50,8 @@ export default {
|
||||
showRawText: '顯示原文',
|
||||
sourceSemantic: '語義匹配',
|
||||
sourceLlm: '大模型輸出',
|
||||
promptTokens: '問題 {count} tokens',
|
||||
completionTokens: '回答 {count} tokens',
|
||||
inputTokens: 'Input {count}',
|
||||
outputTokens: 'Output {count}',
|
||||
sessionTokens: '本輪消耗 {count} tokens',
|
||||
},
|
||||
setting: {
|
||||
|
||||
@@ -62,15 +62,20 @@ const sourceClass = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const usageLabel = computed(() => {
|
||||
const inputUsageLabel = computed(() => {
|
||||
const usage = props.messageMeta?.usage
|
||||
if (!usage)
|
||||
if (!usage || props.inversion)
|
||||
return ''
|
||||
|
||||
if (props.inversion)
|
||||
return t('chat.promptTokens', { count: usage.prompt_tokens })
|
||||
return t('chat.inputTokens', { count: usage.prompt_tokens })
|
||||
})
|
||||
|
||||
return t('chat.completionTokens', { count: usage.completion_tokens })
|
||||
const outputUsageLabel = computed(() => {
|
||||
const usage = props.messageMeta?.usage
|
||||
if (!usage || props.inversion)
|
||||
return ''
|
||||
|
||||
return t('chat.outputTokens', { count: usage.completion_tokens })
|
||||
})
|
||||
|
||||
const options = computed(() => {
|
||||
@@ -130,21 +135,35 @@ function handleRegenerate() {
|
||||
<AvatarComponent :image="inversion" />
|
||||
</div>
|
||||
<div class="overflow-hidden text-sm " :class="[inversion ? 'items-end' : 'items-start']">
|
||||
<div class="flex flex-wrap items-center gap-2 text-xs" :class="[inversion ? 'justify-end' : 'justify-start']">
|
||||
<span class="font-medium text-[#9aa4af] dark:text-neutral-500">{{ dateTime }}</span>
|
||||
<span
|
||||
v-if="sourceLabel"
|
||||
class="rounded-full border px-2.5 py-1 text-[11px] font-medium leading-none"
|
||||
:class="sourceClass"
|
||||
<div class="flex flex-col gap-2" :class="[inversion ? 'items-end' : 'items-start']">
|
||||
<span class="text-xs font-medium text-[#9aa4af] dark:text-neutral-500">{{ dateTime }}</span>
|
||||
<div
|
||||
v-if="sourceLabel || inputUsageLabel || outputUsageLabel"
|
||||
class="flex flex-wrap items-center gap-2 rounded-2xl border border-[#e6edf3] bg-white/85 px-2.5 py-2 shadow-[0_10px_25px_rgba(15,23,42,0.06)] backdrop-blur-sm dark:border-neutral-800 dark:bg-[#14161a]/90"
|
||||
>
|
||||
{{ sourceLabel }}
|
||||
</span>
|
||||
<span
|
||||
v-if="usageLabel"
|
||||
class="rounded-full border border-violet-200 bg-violet-50 px-2.5 py-1 text-[11px] font-medium leading-none text-violet-700 dark:border-violet-900/60 dark:bg-violet-950/40 dark:text-violet-300"
|
||||
>
|
||||
{{ usageLabel }}
|
||||
</span>
|
||||
<div
|
||||
v-if="sourceLabel"
|
||||
class="inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] font-semibold leading-none"
|
||||
:class="sourceClass"
|
||||
>
|
||||
<SvgIcon icon="ri:radar-line" />
|
||||
<span>{{ sourceLabel }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="inputUsageLabel"
|
||||
class="inline-flex items-center gap-1.5 rounded-full border border-violet-200 bg-violet-50 px-2.5 py-1 text-[11px] font-semibold leading-none text-violet-700 dark:border-violet-900/60 dark:bg-violet-950/40 dark:text-violet-300"
|
||||
>
|
||||
<SvgIcon icon="ri:login-circle-line" />
|
||||
<span>{{ inputUsageLabel }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="outputUsageLabel"
|
||||
class="inline-flex items-center gap-1.5 rounded-full border border-fuchsia-200 bg-fuchsia-50 px-2.5 py-1 text-[11px] font-semibold leading-none text-fuchsia-700 dark:border-fuchsia-900/60 dark:bg-fuchsia-950/40 dark:text-fuchsia-300"
|
||||
>
|
||||
<SvgIcon icon="ri:logout-circle-r-line" />
|
||||
<span>{{ outputUsageLabel }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-end gap-1 mt-2"
|
||||
|
||||
@@ -95,45 +95,7 @@ function normalizeResponseMeta(data: Chat.ConversationResponse): {
|
||||
}
|
||||
}
|
||||
|
||||
function buildPromptUsage(usage: Chat.TokenUsage): Chat.TokenUsage {
|
||||
return {
|
||||
prompt_tokens: usage.prompt_tokens,
|
||||
completion_tokens: 0,
|
||||
total_tokens: usage.prompt_tokens,
|
||||
}
|
||||
}
|
||||
|
||||
function buildCompletionUsage(usage: Chat.TokenUsage): Chat.TokenUsage {
|
||||
return {
|
||||
prompt_tokens: 0,
|
||||
completion_tokens: usage.completion_tokens,
|
||||
total_tokens: usage.completion_tokens,
|
||||
}
|
||||
}
|
||||
|
||||
function findQuestionIndex(answerIndex: number) {
|
||||
for (let current = answerIndex - 1; current >= 0; current -= 1) {
|
||||
if (dataSources.value[current]?.inversion)
|
||||
return current
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
||||
|
||||
function updateMessageMeta(questionIndex: number, answerIndex: number, usage: Chat.TokenUsage, source: Chat.ReplySource | null, tokenUsed?: boolean) {
|
||||
if (questionIndex >= 0) {
|
||||
updateChatSome(
|
||||
+uuid,
|
||||
questionIndex,
|
||||
{
|
||||
messageMeta: {
|
||||
tokenUsed,
|
||||
usage: buildPromptUsage(usage),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
function updateMessageMeta(answerIndex: number, usage: Chat.TokenUsage, source: Chat.ReplySource | null, tokenUsed?: boolean) {
|
||||
updateChatSome(
|
||||
+uuid,
|
||||
answerIndex,
|
||||
@@ -141,7 +103,7 @@ function updateMessageMeta(questionIndex: number, answerIndex: number, usage: Ch
|
||||
messageMeta: {
|
||||
source,
|
||||
tokenUsed,
|
||||
usage: buildCompletionUsage(usage),
|
||||
usage,
|
||||
},
|
||||
},
|
||||
)
|
||||
@@ -182,8 +144,6 @@ async function onConversation() {
|
||||
)
|
||||
scrollToBottom()
|
||||
|
||||
const questionIndex = dataSources.value.length - 1
|
||||
|
||||
loading.value = true
|
||||
prompt.value = ''
|
||||
|
||||
@@ -250,7 +210,7 @@ async function onConversation() {
|
||||
)
|
||||
|
||||
if (responseMeta.source || responseMeta.usage || responseMeta.tokenUsed !== undefined)
|
||||
updateMessageMeta(questionIndex, answerIndex, nextUsage, responseMeta.source, responseMeta.tokenUsed)
|
||||
updateMessageMeta(answerIndex, nextUsage, responseMeta.source, responseMeta.tokenUsed)
|
||||
|
||||
if (responseMeta.usage && !usageApplied) {
|
||||
accumulatedUsage = nextUsage
|
||||
@@ -343,9 +303,7 @@ async function onRegenerate(index: number) {
|
||||
options = { ...requestOptions.options }
|
||||
|
||||
loading.value = true
|
||||
|
||||
let accumulatedUsage = createEmptyUsage()
|
||||
const questionIndex = findQuestionIndex(index)
|
||||
|
||||
updateChat(
|
||||
+uuid,
|
||||
@@ -401,7 +359,7 @@ async function onRegenerate(index: number) {
|
||||
)
|
||||
|
||||
if (responseMeta.source || responseMeta.usage || responseMeta.tokenUsed !== undefined)
|
||||
updateMessageMeta(questionIndex, index, nextUsage, responseMeta.source, responseMeta.tokenUsed)
|
||||
updateMessageMeta(index, nextUsage, responseMeta.source, responseMeta.tokenUsed)
|
||||
|
||||
if (responseMeta.usage && !usageApplied) {
|
||||
accumulatedUsage = nextUsage
|
||||
|
||||
Reference in New Issue
Block a user