wip: objectTrimmer
This commit is contained in:
@@ -5,6 +5,7 @@ import type {ChatMessage, ChatMessageId, ChatSessionId} from "~/typings/llm";
|
||||
import {useHistory} from "~/composables/useHistory";
|
||||
import {uuidv4} from "@uniiem/uuid";
|
||||
import {useLLM} from "~/composables/useLLM";
|
||||
import {objectTrimmer} from "~/utils/object-trimmer";
|
||||
|
||||
useHead({
|
||||
title: '聊天 | XSH AI'
|
||||
@@ -79,6 +80,13 @@ const handleClickCreateSession = () => {
|
||||
])
|
||||
// 切换到新的会话
|
||||
selectCurrentSessionId(sessionId)
|
||||
nextTick(() => {
|
||||
insetMessage({
|
||||
id: uuidv4(),
|
||||
role: 'assistant',
|
||||
content: '你好,有什么可以帮助你的吗?',
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,7 +125,14 @@ const handleClickSend = (event: any) => {
|
||||
content: '',
|
||||
})
|
||||
// 请求模型回复
|
||||
useLLM(getMessages(), {
|
||||
const trimmedMessages = objectTrimmer<ChatMessage>(
|
||||
getMessages(),
|
||||
200,
|
||||
{
|
||||
participatingFields: ['content']
|
||||
}
|
||||
)
|
||||
useLLM(trimmedMessages, {
|
||||
modelTag: 'spark3_5'
|
||||
}).then(reply => {
|
||||
modifyMessageContent(assistantReplyId, reply)
|
||||
@@ -181,19 +196,21 @@ onMounted(() => {
|
||||
shadow-sidebar border-r border-transparent dark:border-neutral-700">
|
||||
<div class="flex-1 flex flex-col overflow-auto overflow-x-hidden">
|
||||
<!-- list -->
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="flex flex-col gap-3 relative">
|
||||
<!-- ClientOnly avoids hydrate exception -->
|
||||
<ClientOnly>
|
||||
<ChatItem
|
||||
v-for="(session, i) in chatSessions"
|
||||
:chat-session="session" :key="i"
|
||||
:active="session.id === currentSessionId"
|
||||
@click="selectCurrentSessionId(session.id)"
|
||||
@remove="() => {
|
||||
<TransitionGroup name="chat-item">
|
||||
<ChatItem
|
||||
v-for="session in chatSessions"
|
||||
:chat-session="session" :key="session.id"
|
||||
:active="session.id === currentSessionId"
|
||||
@click="selectCurrentSessionId(session.id)"
|
||||
@remove="() => {
|
||||
chatSessions.splice(chatSessions.findIndex(s => s.id === session.id), 1)
|
||||
session.id === currentSessionId && selectCurrentSessionId()
|
||||
}"
|
||||
/>
|
||||
/>
|
||||
</TransitionGroup>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
</div>
|
||||
@@ -265,4 +282,19 @@ onMounted(() => {
|
||||
.message-enter-from {
|
||||
@apply translate-y-4 opacity-0;
|
||||
}
|
||||
|
||||
.chat-item-move,
|
||||
.chat-item-enter-active,
|
||||
.chat-item-leave-active {
|
||||
@apply transition-all duration-300;
|
||||
}
|
||||
|
||||
.chat-item-enter-from,
|
||||
.chat-item-leave-to {
|
||||
@apply opacity-0 scale-90;
|
||||
}
|
||||
|
||||
.chat-item-leave-active {
|
||||
@apply absolute inset-x-0;
|
||||
}
|
||||
</style>
|
||||
26
utils/object-trimmer.ts
Normal file
26
utils/object-trimmer.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
const objectTrimmer = <T>(
|
||||
objectList: T[],
|
||||
length: number,
|
||||
{
|
||||
participatingFields = [],
|
||||
trimFromStart = true
|
||||
}: {
|
||||
participatingFields: (keyof T)[],
|
||||
trimFromStart?: boolean
|
||||
}) => {
|
||||
let participatingLength = 0
|
||||
let i = objectList.length - 1
|
||||
while (i >= 0) {
|
||||
participatingLength = 0
|
||||
for (const field of participatingFields) {
|
||||
participatingLength += JSON.stringify(objectList[i][field]).length
|
||||
if (participatingLength > length) {
|
||||
break
|
||||
}
|
||||
}
|
||||
i--
|
||||
}
|
||||
return trimFromStart ? objectList.slice(i + 1) : objectList.slice(0, i + 1)
|
||||
}
|
||||
|
||||
export {objectTrimmer}
|
||||
Reference in New Issue
Block a user