优化会话标题生成逻辑,增加消息限制与格式处理
This commit is contained in:
+32
-11
@@ -4,7 +4,10 @@ import { type OpencodeRuntimeAdapter } from "../runtime/opencode.js";
|
||||
|
||||
import { collectTextContent } from "./chatStream.js";
|
||||
|
||||
const TITLE_PROMPT_TIMEOUT_MS = 2500;
|
||||
const TITLE_PROMPT_TIMEOUT_MS = 5000;
|
||||
const TITLE_CONTEXT_MESSAGE_LIMIT = 40;
|
||||
const TITLE_CONTEXT_CHAR_LIMIT = 2400;
|
||||
const TITLE_CONTEXT_MESSAGE_CHAR_LIMIT = 240;
|
||||
|
||||
const buildSessionTitle = (message: string) => {
|
||||
const normalized = message.replace(/\s+/g, " ").trim();
|
||||
@@ -18,7 +21,7 @@ const buildTitleConversationContext = async (
|
||||
runtime: OpencodeRuntimeAdapter,
|
||||
sessionId: string,
|
||||
) => {
|
||||
const messages = await runtime.messages(sessionId, 12);
|
||||
const messages = await runtime.messages(sessionId, TITLE_CONTEXT_MESSAGE_LIMIT);
|
||||
const recentMessages = messages
|
||||
.filter(
|
||||
(message) =>
|
||||
@@ -26,19 +29,35 @@ const buildTitleConversationContext = async (
|
||||
)
|
||||
.map((message) => ({
|
||||
role: message.info.role,
|
||||
content: collectTextContent(message.parts).replace(/\s+/g, " ").trim(),
|
||||
content: collectTextContent(message.parts)
|
||||
.replace(/\s+/g, " ")
|
||||
.trim()
|
||||
.slice(0, TITLE_CONTEXT_MESSAGE_CHAR_LIMIT),
|
||||
}))
|
||||
.filter((message) => message.content.length > 0)
|
||||
.slice(-6);
|
||||
.filter((message) => message.content.length > 0);
|
||||
|
||||
if (recentMessages.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return recentMessages
|
||||
.map((message) => `${message.role === "user" ? "用户" : "助手"}:${message.content}`)
|
||||
.join("\n")
|
||||
.slice(0, 2400);
|
||||
const formattedMessages = recentMessages.map(
|
||||
(message) => `${message.role === "user" ? "用户" : "助手"}:${message.content}`,
|
||||
);
|
||||
const fullConversation = formattedMessages.join("\n");
|
||||
if (fullConversation.length <= TITLE_CONTEXT_CHAR_LIMIT) {
|
||||
return fullConversation;
|
||||
}
|
||||
|
||||
const headCount = Math.min(4, formattedMessages.length);
|
||||
const tailCount = Math.min(8, Math.max(0, formattedMessages.length - headCount));
|
||||
const middleOmitted = formattedMessages.length > headCount + tailCount;
|
||||
const summary = [
|
||||
...formattedMessages.slice(0, headCount),
|
||||
...(middleOmitted ? ["……(中间省略若干轮对话)"] : []),
|
||||
...formattedMessages.slice(-tailCount),
|
||||
].join("\n");
|
||||
|
||||
return summary.slice(0, TITLE_CONTEXT_CHAR_LIMIT);
|
||||
};
|
||||
|
||||
const normalizeGeneratedTitle = (rawTitle: string, fallback: string) => {
|
||||
@@ -75,15 +94,17 @@ export const generateSessionTitle = async (
|
||||
titleSession.id,
|
||||
[
|
||||
"你是会话标题生成器。",
|
||||
"请根据用户问题生成一个 8-16 字中文标题。",
|
||||
"请根据下面整段多轮对话生成一个 8-16 字中文标题。",
|
||||
"要求:简洁、可读、避免标点、不要引号、不要解释。",
|
||||
"请优先概括最近这轮对话的核心任务或结论。",
|
||||
"先理解完整对话,再概括核心任务或结论。",
|
||||
"不要直接照抄用户任一条消息原文。",
|
||||
"只输出标题本身。",
|
||||
"",
|
||||
conversation,
|
||||
].join("\n"),
|
||||
)
|
||||
.then(async () => {
|
||||
await runtime.waitForSessionIdle(titleSession.id, TITLE_PROMPT_TIMEOUT_MS);
|
||||
const messages = await runtime.messages(titleSession.id, 20);
|
||||
const assistantMessage = [...messages]
|
||||
.reverse()
|
||||
|
||||
Reference in New Issue
Block a user