import type { CallableQAItem } from "./types"; export type ChatRole = "assistant" | "user"; export type ChatMessage = { id: string; role: ChatRole; content: string; source?: string; boundary?: string; feedback?: "liked" | "disliked"; createdAt: string; }; export type ChatSession = { id: string; title: string; preview: string; messages: ChatMessage[]; updatedAt: string; questionCount: number; }; export type SuggestedQuestion = { id: string; text: string; tags: string[]; }; export const suggestedQuestions: SuggestedQuestion[] = [ { id: "parent-child-emotion", text: "孩子一写作业就发脾气,我怎么接住他的情绪?", tags: ["亲子关系", "情绪"] }, { id: "self-growth", text: "我知道要行动,但总是拖延,应该先从哪里开始?", tags: ["个人成长", "行动力"] }, { id: "marriage-talk", text: "伴侣不愿意沟通,我怎么表达才不容易吵起来?", tags: ["婚姻关系", "沟通"] } ]; export const initialMessages: ChatMessage[] = [ { id: "welcome", role: "assistant", content: "你好,我是千问千答助手。你可以把最近遇到的亲子、关系、情绪或行动问题发给我,我会优先基于已审核的答疑资产给你一个可落地的回应。", boundary: "当前为 H5 体验版,一期免登录试用;问答答案只读取后端可调用库。", createdAt: "09:30" } ]; export function createEmptySession(): ChatSession { return { id: `session-${Date.now()}`, title: "新的问答", preview: "还没有开始提问", messages: initialMessages, updatedAt: new Date().toISOString(), questionCount: 0 }; } export function summarizeSession(sessionId: string, messages: ChatMessage[]): ChatSession { const userMessages = messages.filter((message) => message.role === "user"); const lastMessage = [...messages].reverse().find((message) => message.role === "assistant" || message.role === "user"); const firstQuestion = userMessages[0]?.content; return { id: sessionId, title: firstQuestion ? firstQuestion.slice(0, 24) : "新的问答", preview: lastMessage?.content.slice(0, 42) ?? "还没有开始提问", messages, updatedAt: new Date().toISOString(), questionCount: userMessages.length }; } function scoreQuestion(question: string, qa: CallableQAItem): number { const haystack = [ qa.standard_question, qa.standard_answer, qa.primary_topic, qa.course_stage, ...qa.problem_tags, ...qa.similar_questions ].join(" "); return Array.from(new Set(question.trim().split(""))).reduce((score, char) => { if (!char.trim()) return score; return haystack.includes(char) ? score + 1 : score; }, 0); } export function findQaAnswer(question: string, qaItems: CallableQAItem[]) { if (qaItems.length === 0) { return null; } const [best] = [...qaItems].sort((left, right) => scoreQuestion(question, right) - scoreQuestion(question, left)); return best ?? null; }