预设兼容:按真实抓包对齐装配与包装层,补上声明式工具与预设正则。
- 装配只认 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:
@@ -86,7 +86,20 @@ const fmt = (v) => {
|
||||
if (v === undefined) return "(无)";
|
||||
if (v === null) return "null";
|
||||
if (typeof v === "string") return v.length > 60 ? JSON.stringify(v.slice(0, 60)) + "…" : JSON.stringify(v);
|
||||
if (Array.isArray(v)) { const names = v.map((x) => (x && x.function && x.function.name) || (x && x.name) || "").filter(Boolean); return "[" + v.length + " 项" + (names.length ? ": " + names.join(", ") : "") + "]"; }
|
||||
if (Array.isArray(v)) {
|
||||
const tools = v.filter((x) => x && x.function && x.function.name);
|
||||
if (tools.length) {
|
||||
return tools
|
||||
.map((t) => {
|
||||
const fn = t.function;
|
||||
const props = Object.keys((fn.parameters && fn.parameters.properties) || {});
|
||||
return fn.name + "(参数: " + (props.join(",") || "-") + "; 描述 " + String(fn.description || "").length + " 字)";
|
||||
})
|
||||
.join("; ");
|
||||
}
|
||||
const names = v.map((x) => (x && x.function && x.function.name) || (x && x.name) || "").filter(Boolean);
|
||||
return "[" + v.length + " 项" + (names.length ? ": " + names.join(", ") : "") + "]";
|
||||
}
|
||||
if (typeof v === "object") return JSON.stringify(v).slice(0, 200);
|
||||
return String(v);
|
||||
};
|
||||
@@ -166,6 +179,72 @@ function unattributed(entries, messages) {
|
||||
return out.length ? out.join("\n") : "(没有)";
|
||||
}
|
||||
|
||||
function onlyOnOneSide(stMsgs, waMsgs) {
|
||||
const key = (m) => stripWs(m.content).slice(0, 40);
|
||||
const stKeys = new Set(stMsgs.map(key));
|
||||
const waKeys = new Set(waMsgs.map(key));
|
||||
const onlySt = stMsgs.filter((m) => !waKeys.has(key(m)));
|
||||
const onlyWa = waMsgs.filter((m) => !stKeys.has(key(m)));
|
||||
const fmtList = (list) =>
|
||||
list.length
|
||||
? list.map((m, i) => "- [" + m.role + "] " + m.content.length + " 字:" + stripWs(m.content).slice(0, 60)).join("\n")
|
||||
: "(没有)";
|
||||
return { onlySt, onlyWa, text: "**只在酒馆出现**:" + onlySt.length + " 条\n\n" + fmtList(onlySt) + "\n\n**只在本仓库出现**:" + onlyWa.length + " 条\n\n" + fmtList(onlyWa) };
|
||||
}
|
||||
|
||||
/** 把某一侧的最终 messages 原文落盘,方便逐字比对。 */
|
||||
function writeMessageDump(outDir, label, msgs) {
|
||||
mkdirSync(outDir, { recursive: true });
|
||||
const lines = [];
|
||||
msgs.forEach((m, i) => {
|
||||
const name = m.name ? " name=" + m.name : "";
|
||||
lines.push("#" + i + " [" + m.role + "]" + name + " " + m.content.length + " 字");
|
||||
lines.push(m.content);
|
||||
lines.push("");
|
||||
});
|
||||
writeFileSync(outDir + "/messages-" + label + ".txt", lines.join("\n"), "utf8");
|
||||
}
|
||||
|
||||
/** 按正文前 40 字把两边消息配对,并排打印。 */
|
||||
function sideBySide(stMsgs, waMsgs) {
|
||||
const key = (m) => stripWs(m.content).slice(0, 40);
|
||||
const waIndex = new Map();
|
||||
const used = new Set();
|
||||
waMsgs.forEach((m, j) => {
|
||||
const k = key(m);
|
||||
if (!waIndex.has(k)) waIndex.set(k, []);
|
||||
waIndex.get(k).push(j);
|
||||
});
|
||||
const rows = [];
|
||||
const pairedWa = new Set();
|
||||
stMsgs.forEach((m, i) => {
|
||||
const candidates = (waIndex.get(key(m)) || []).filter((j) => !pairedWa.has(j));
|
||||
const j = candidates.length ? candidates[0] : null;
|
||||
if (j !== null) pairedWa.add(j);
|
||||
const left = "#" + i + " [" + m.role + "] " + m.content.length + " 字: " + stripWs(m.content).slice(0, 50);
|
||||
const right =
|
||||
j === null
|
||||
? "—"
|
||||
: "#" + j + " [" + waMsgs[j].role + "] " + waMsgs[j].content.length + " 字: " + stripWs(waMsgs[j].content).slice(0, 50);
|
||||
let verdict = "对上了";
|
||||
if (j === null) verdict = "**只在酒馆**";
|
||||
else if (stMsgs[i].role !== waMsgs[j].role) verdict = "**角色不同**";
|
||||
else if (stMsgs[i].content.trim() !== waMsgs[j].content.trim()) verdict = "内容有差";
|
||||
rows.push("| " + left + " | " + right + " | " + verdict + " |");
|
||||
});
|
||||
waMsgs.forEach((m, j) => {
|
||||
if (pairedWa.has(j)) return;
|
||||
rows.push(
|
||||
"| — | #" + j + " [" + m.role + "] " + m.content.length + " 字: " + stripWs(m.content).slice(0, 50) + " | **只在本仓库** |",
|
||||
);
|
||||
});
|
||||
return [
|
||||
"| 酒馆 | 本仓库 | 结果 |",
|
||||
"| --- | --- | --- |",
|
||||
...rows,
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
function main() {
|
||||
const args = readArgs(process.argv.slice(2));
|
||||
if (!args.st || !args.wa) throw new Error("缺少 --st / --wa");
|
||||
@@ -209,6 +288,13 @@ function main() {
|
||||
lines.push("");
|
||||
lines.push(messageTable("本仓库", waMsgs, entries));
|
||||
lines.push("");
|
||||
const side = onlyOnOneSide(stMsgs, waMsgs);
|
||||
writeMessageDump(args.out, "st", stMsgs);
|
||||
writeMessageDump(args.out, "wa", waMsgs);
|
||||
lines.push("## 4. 只在一侧出现的消息(按正文前 40 字配对)");
|
||||
lines.push("");
|
||||
lines.push(side.text);
|
||||
lines.push("");
|
||||
lines.push("## 4. 开头对不上任何预设条目的消息");
|
||||
lines.push("");
|
||||
lines.push("酒馆:");
|
||||
@@ -218,6 +304,10 @@ function main() {
|
||||
lines.push("本仓库:");
|
||||
lines.push("");
|
||||
lines.push(unattributed(entries, waMsgs));
|
||||
lines.push("## 5. 最终 messages 并排(全文见同目录 messages-st.txt / messages-wa.txt)");
|
||||
lines.push("");
|
||||
lines.push(sideBySide(stMsgs, waMsgs));
|
||||
lines.push("");
|
||||
lines.push("");
|
||||
|
||||
mkdirSync(args.out, { recursive: true });
|
||||
@@ -232,6 +322,7 @@ function main() {
|
||||
console.log("[diff] 报告: " + reportFile);
|
||||
console.log("[diff] 字段: " + fields.length + " 项, 仅酒馆 " + onlySt + ", 仅本仓库 " + onlyWa + ", 不同 " + diffCount);
|
||||
console.log("[diff] 消息: 酒馆 " + stMsgs.length + " 条 / 本仓库 " + waMsgs.length + " 条");
|
||||
console.log("[diff] 只在酒馆 " + side.onlySt.length + " 条,只在本仓库 " + side.onlyWa.length + " 条");
|
||||
if (entriesOnlySt.length) console.log("[diff] 只在酒馆出现的预设条目: " + entriesOnlySt.map((e) => e.name).join("、"));
|
||||
if (entriesOnlyWa.length) console.log("[diff] 只在本仓库出现的预设条目: " + entriesOnlyWa.map((e) => e.name).join("、"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user