@musnows/scriverse 0.8.2 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ai.js CHANGED
@@ -3617,16 +3617,20 @@ export class AiManager {
3617
3617
  const conversationBefore = input.conversationId
3618
3618
  ? this.store.getAiConversationTitleContext(input.conversationId, input.workId)
3619
3619
  : null;
3620
- const firstUserMessage = conversationBefore?.messages.length === 1 && conversationBefore.messages[0]?.role === "user"
3621
- ? conversationBefore.messages[0]
3622
- : null;
3620
+ const userMessages = conversationBefore?.messages.filter((message) => message.role === "user") ?? [];
3621
+ const assistantMessages = conversationBefore?.messages.filter((message) => message.role === "assistant") ?? [];
3622
+ const firstUserMessage = userMessages[0] ?? null;
3623
3623
  const firstUserContent = firstUserMessage?.content ?? "";
3624
3624
  const titleSettings = this.store.getWorkAiSettings(input.workId);
3625
3625
  const titleModelId = typeof titleSettings.titleGenerationModelId === "string" ? titleSettings.titleGenerationModelId : "";
3626
3626
  const defaultTitle = firstUserContent ? defaultAiConversationTitle(firstUserContent) : "";
3627
+ const isCompletingSecondAssistantTurn = conversationBefore?.messages.at(-1)?.role === "user"
3628
+ && userMessages.length === 2
3629
+ && assistantMessages.length === 1;
3627
3630
  const shouldGenerateTitle = Boolean(input.conversationId
3628
3631
  && firstUserContent
3629
3632
  && titleModelId
3633
+ && isCompletingSecondAssistantTurn
3630
3634
  && (conversationBefore?.title === "新对话" || conversationBefore?.title === defaultTitle));
3631
3635
  const processStartedAt = process.hrtime.bigint();
3632
3636
  let persistedConversationMessage = null;
@@ -3668,7 +3672,10 @@ export class AiManager {
3668
3672
  }, true)
3669
3673
  : persistedConversationMessage;
3670
3674
  if (shouldGenerateTitle && conversationMessage && input.conversationId) {
3671
- void this.generateConversationTitle(input.workId, input.conversationId, titleModelId, firstUserContent, generated.content, defaultTitle).catch((error) => {
3675
+ void this.generateConversationTitle(input.workId, input.conversationId, titleModelId, [
3676
+ ...(conversationBefore?.messages ?? []),
3677
+ { role: "assistant", content: generated.content }
3678
+ ], defaultTitle).catch((error) => {
3672
3679
  logger.warn("ai.conversation_title.failed", { workId: input.workId, conversationId: input.conversationId, error: aiErrorForLog(error) });
3673
3680
  });
3674
3681
  }
@@ -3683,17 +3690,20 @@ export class AiManager {
3683
3690
  ...(conversationMessage ? { conversationMessage } : {})
3684
3691
  };
3685
3692
  }
3686
- async generateConversationTitle(workId, conversationId, modelId, prompt, response, fallbackTitle) {
3693
+ async generateConversationTitle(workId, conversationId, modelId, messages, fallbackTitle) {
3687
3694
  try {
3695
+ const conversation = messages.map((message) => {
3696
+ const speaker = message.role === "user" ? "用户" : "助手";
3697
+ return `<${speaker}>\n${Array.from(message.content).slice(0, 3_000).join("")}\n</${speaker}>`;
3698
+ }).join("\n\n");
3688
3699
  const generated = await this.generate({
3689
3700
  workId,
3690
3701
  taskType: "chat",
3691
3702
  instruction: [
3692
- "请根据下面这次对话的第一轮用户提问和助手回答,生成一个简洁、准确的会话标题。",
3703
+ "请根据下面前两轮用户与助手的对话,生成一个简洁、准确的会话标题。",
3693
3704
  "标题应概括用户真正想解决的主题,不要复述完整句子。",
3694
3705
  "只输出标题本身,不要引号、编号、Markdown、解释或句末标点;标题不超过 15 个汉字或 30 个字符。",
3695
- `<用户提问>\n${Array.from(prompt).slice(0, 6_000).join("")}\n</用户提问>`,
3696
- `<助手回答>\n${Array.from(response).slice(0, 6_000).join("")}\n</助手回答>`
3706
+ `<对话记录>\n${conversation}\n</对话记录>`
3697
3707
  ].join("\n\n"),
3698
3708
  scope: { type: "none" },
3699
3709
  modelId,