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 {useHistory} from "~/composables/useHistory";
|
||||||
import {uuidv4} from "@uniiem/uuid";
|
import {uuidv4} from "@uniiem/uuid";
|
||||||
import {useLLM} from "~/composables/useLLM";
|
import {useLLM} from "~/composables/useLLM";
|
||||||
|
import {objectTrimmer} from "~/utils/object-trimmer";
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: '聊天 | XSH AI'
|
title: '聊天 | XSH AI'
|
||||||
@@ -79,6 +80,13 @@ const handleClickCreateSession = () => {
|
|||||||
])
|
])
|
||||||
// 切换到新的会话
|
// 切换到新的会话
|
||||||
selectCurrentSessionId(sessionId)
|
selectCurrentSessionId(sessionId)
|
||||||
|
nextTick(() => {
|
||||||
|
insetMessage({
|
||||||
|
id: uuidv4(),
|
||||||
|
role: 'assistant',
|
||||||
|
content: '你好,有什么可以帮助你的吗?',
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,7 +125,14 @@ const handleClickSend = (event: any) => {
|
|||||||
content: '',
|
content: '',
|
||||||
})
|
})
|
||||||
// 请求模型回复
|
// 请求模型回复
|
||||||
useLLM(getMessages(), {
|
const trimmedMessages = objectTrimmer<ChatMessage>(
|
||||||
|
getMessages(),
|
||||||
|
200,
|
||||||
|
{
|
||||||
|
participatingFields: ['content']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
useLLM(trimmedMessages, {
|
||||||
modelTag: 'spark3_5'
|
modelTag: 'spark3_5'
|
||||||
}).then(reply => {
|
}).then(reply => {
|
||||||
modifyMessageContent(assistantReplyId, reply)
|
modifyMessageContent(assistantReplyId, reply)
|
||||||
@@ -181,12 +196,13 @@ onMounted(() => {
|
|||||||
shadow-sidebar border-r border-transparent dark:border-neutral-700">
|
shadow-sidebar border-r border-transparent dark:border-neutral-700">
|
||||||
<div class="flex-1 flex flex-col overflow-auto overflow-x-hidden">
|
<div class="flex-1 flex flex-col overflow-auto overflow-x-hidden">
|
||||||
<!-- list -->
|
<!-- list -->
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3 relative">
|
||||||
<!-- ClientOnly avoids hydrate exception -->
|
<!-- ClientOnly avoids hydrate exception -->
|
||||||
<ClientOnly>
|
<ClientOnly>
|
||||||
|
<TransitionGroup name="chat-item">
|
||||||
<ChatItem
|
<ChatItem
|
||||||
v-for="(session, i) in chatSessions"
|
v-for="session in chatSessions"
|
||||||
:chat-session="session" :key="i"
|
:chat-session="session" :key="session.id"
|
||||||
:active="session.id === currentSessionId"
|
:active="session.id === currentSessionId"
|
||||||
@click="selectCurrentSessionId(session.id)"
|
@click="selectCurrentSessionId(session.id)"
|
||||||
@remove="() => {
|
@remove="() => {
|
||||||
@@ -194,6 +210,7 @@ onMounted(() => {
|
|||||||
session.id === currentSessionId && selectCurrentSessionId()
|
session.id === currentSessionId && selectCurrentSessionId()
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
</TransitionGroup>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -265,4 +282,19 @@ onMounted(() => {
|
|||||||
.message-enter-from {
|
.message-enter-from {
|
||||||
@apply translate-y-4 opacity-0;
|
@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>
|
</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