预设兼容:按真实抓包对齐装配与包装层,补上声明式工具与预设正则。

- 装配只认 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:真假上游抓包对比工具、三份预设的机制结论与实测报告
This commit is contained in:
2026-10-23 00:13:08 +08:00
parent ed09e5c831
commit 9dc927282f
94 changed files with 11558 additions and 413 deletions
+62 -1
View File
@@ -1,6 +1,7 @@
import { describe, expect, it } from "vitest";
import {
appendDialogueHistoryTurn,
parseHistoryMessages,
projectDialogueHistory,
buildHistoryFallback,
isDialogueHistoryRef,
@@ -14,18 +15,78 @@ import {
synthesizeContextOrderFromWorkers,
} from "../src/skills/context-order.js";
describe("parseHistoryMessages", () => {
it("turns ## 用户 / ## 助手 blocks into real turns", () => {
const raw = appendDialogueHistoryTurn(
appendDialogueHistoryTurn("", { role: "助手", text: "门开了。" }),
{ role: "用户", text: "我推门。" },
);
expect(parseHistoryMessages(raw)).toEqual([
{ role: "assistant", content: "门开了。" },
{ role: "user", content: "我推门。" },
]);
});
it("accepts 【用户】 and 用户:single-line forms", () => {
expect(parseHistoryMessages("【用户】\n你好\n\n【助手】\n在。")).toEqual([
{ role: "user", content: "你好" },
{ role: "assistant", content: "在。" },
]);
expect(parseHistoryMessages("用户:你好\n助手:在。")).toEqual([
{ role: "user", content: "你好" },
{ role: "assistant", content: "在。" },
]);
});
it("keeps the projection note on the first turn", () => {
const turns = parseHistoryMessages(
"(仅最近 20 段,更早已省略)\n\n## 用户\n\n你好",
);
expect(turns).toHaveLength(1);
expect(turns[0]!.content).toContain("仅最近");
expect(turns[0]!.content).toContain("你好");
});
it("returns [] for text without role markers", () => {
expect(parseHistoryMessages("一段无结构的前情提要")).toEqual([]);
});
it("keeps a body line that looks like markdown heading", () => {
const raw = "## 用户\n\n我说## 这不是块头\n\n## 助手\n\n嗯";
const turns = parseHistoryMessages(raw);
expect(turns).toHaveLength(2);
expect(turns[0]!.content).toContain("这不是块头");
});
});
describe("dialogue history projection", () => {
it("recognizes history refs and projects by level", () => {
expect(isDialogueHistoryRef("对话.历史")).toBe(true);
expect(isDialogueHistoryRef("history")).toBe(true);
const long = Array.from({ length: 30 }, (_, i) => `## 用户\n\n第${i}句`).join(
const long = Array.from({ length: 60 }, (_, i) => `## 用户\n\n第${i}句`).join(
"\n\n",
);
const summary = projectDialogueHistory(long, "summary");
expect(summary).toContain("仅最近");
// 裁到 n 段(summary = 20)
expect(summary.split("## 用户").length - 1).toBe(20);
expect(projectDialogueHistory(long, "fixed")).toContain("不注入");
});
it("keeps the whole window until it doubles(滞回,不每轮位移)", () => {
const turn = (n: number) =>
Array.from({ length: n }, (_, i) => `## 用户\n\n第${i}句`).join("\n\n");
// 20~40 段(summary 的 n=20,高水位=40)原样全给,前缀稳定
expect(projectDialogueHistory(turn(30), "summary")).not.toContain("仅最近");
expect(projectDialogueHistory(turn(30), "summary").split("## 用户").length - 1).toBe(
30,
);
// 超过高水位才裁,且一次裁到 20
expect(projectDialogueHistory(turn(41), "summary").split("## 用户").length - 1).toBe(
20,
);
});
it("assembles history tag in flat segment order", () => {
const bb = new Blackboard();
bb.write({