Files
writing-agent/src/preset/examples.ts
T
chenmoranzhi 9dc927282f 预设兼容:按真实抓包对齐装配与包装层,补上声明式工具与预设正则。
- 装配只认 prompt_order.enabled;squash_system_messages 只合并相邻 system(新增 system 档,连接符按酒馆用单换行)
- 包装层:new_chat_prompt、示例对话(new_example_chat_prompt + <START> 切段 + name)、角色卡三块与 personality_format/scenario_format、{{user}}/{{char}} 取值、任务契约并进预设条目
- 工具协议:按 ToolBindings / 伪工具协议数据声明真 tools(presetToolPolicy=preset),工具描述用到的条目不再重复作为消息发出
- 正则:promptOnly 作用于对话历史(含 depth 过滤)、写入时脚本改写回复;{{//}} 注释按配平扫描
- tools/st-request-diff:真假上游抓包对比工具、三份预设的机制结论与实测报告
2026-10-23 00:13:08 +08:00

70 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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`):
* - 按 `<START>` 分块;
* - 块内以 `用户名:` / `角色名:` 开头的行切换说话人,其余行算续行;
* - 每条消息 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(/<START>/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;
}