import type { ChatMessage } from "../llm/client.js"; /** 酒馆给示例对话消息打的 name(不是角色名)。 */ export const EXAMPLE_USER_NAME = "example_user"; export const EXAMPLE_ASSISTANT_NAME = "example_assistant"; /** * 把酒馆 `mes_example` 切成示例消息(对应 `openai.js` 的 `setOpenAIMessageExamples` + * `parseExampleIntoIndividual`): * - 按 `` 分块; * - 块内以 `用户名:` / `角色名:` 开头的行切换说话人,其余行算续行; * - 每条消息 role 都是 system,name 是 example_user / example_assistant, * 正文去掉 `名字:` 前缀。 * 传进来的 text 应该已经展开过宏(`{{user}}` / `{{char}}`),否则名字对不上。 */ export function parseExampleDialogue(params: { text: string; userName: string; charName: string; }): ChatMessage[][] { const text = (params.text ?? "").replace(/\r/g, ""); if (!text.trim()) return []; const userName = params.userName.trim(); const charName = params.charName.trim(); const blocks = text .split(//i) .map((block) => block.trim()) .filter(Boolean); const source = blocks.length > 0 ? blocks : [text.trim()]; const out: ChatMessage[][] = []; for (const block of source) { const messages: ChatMessage[] = []; let speaker: "user" | "assistant" | null = null; let lines: string[] = []; const flush = () => { const content = lines.join("\n").trim(); if (speaker && content) { messages.push({ role: "system", content, name: speaker === "user" ? EXAMPLE_USER_NAME : EXAMPLE_ASSISTANT_NAME, }); } lines = []; }; for (const rawLine of block.split("\n")) { const line = rawLine.replace(/\r$/, ""); if (userName && line.startsWith(`${userName}:`)) { flush(); speaker = "user"; lines.push(line.slice(userName.length + 1)); continue; } if (charName && line.startsWith(`${charName}:`)) { flush(); speaker = "assistant"; lines.push(line.slice(charName.length + 1)); continue; } lines.push(line); } flush(); if (messages.length > 0) out.push(messages); } return out; }