volunteer-secondary/src/store/ai.ts

80 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
export type AiRole = 'user' | 'assistant' | 'system'
export interface AiMessage {
id: string
role: AiRole
content: string
/** 是否仍在流式生成中,用于 UI 展示打字光标 */
pending?: boolean
/** 标记本条消息是否出错UI 显示重试按钮 */
error?: boolean
/** 仅 assistant 消息使用:本轮回答结束后由大模型给出的追问建议 */
recommendQuestions?: string[]
createdAt: number
}
export const useAiStore = defineStore(
'ai',
() => {
const messages = ref<AiMessage[]>([])
/** 一组对话共用同一个 thread跨多轮维持上下文 */
const threadId = ref('')
const messageCount = computed(() => messages.value.length)
function ensureThreadId() {
if (!threadId.value) {
threadId.value = `thread_id_${Date.now()}${Math.floor(Math.random() * 10000)}`
}
return threadId.value
}
function addMessage(message: AiMessage) {
messages.value.push(message)
}
function updateMessage(id: string, patch: Partial<AiMessage>) {
const target = messages.value.find(m => m.id === id)
if (!target) {
return
}
Object.assign(target, patch)
}
function appendDelta(id: string, delta: string) {
const target = messages.value.find(m => m.id === id)
if (!target) {
return
}
target.content += delta
}
function removeMessage(id: string) {
messages.value = messages.value.filter(m => m.id !== id)
}
function clear() {
messages.value = []
threadId.value = ''
}
return {
messages,
threadId,
messageCount,
ensureThreadId,
addMessage,
updateMessage,
appendDelta,
removeMessage,
clear,
}
},
{
persist: true,
},
)