e53319039e
Pull Kimi's "搜索网页" panel results into the regular citation source flow, drop the dedicated-citation-panel branch on the server side, and unwrap Kimi redirect URLs so citation source items resolve to the real target host. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
139 lines
4.4 KiB
TypeScript
139 lines
4.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import { __kimiTestUtils } from "./kimi";
|
|
|
|
const {
|
|
buildSourceItem,
|
|
classifyKimiSources,
|
|
mergeKimiSourceLinksIntoContentSnapshot,
|
|
normalizeUrl,
|
|
} = __kimiTestUtils;
|
|
|
|
function buildSnapshot(overrides: Partial<Parameters<typeof classifyKimiSources>[0]>): Parameters<typeof classifyKimiSources>[0] {
|
|
return {
|
|
url: "https://www.kimi.com/chat/test",
|
|
title: "Kimi",
|
|
currentModelLabel: "K2.6 思考",
|
|
loginRequired: false,
|
|
loginReason: null,
|
|
busy: false,
|
|
busySignals: [],
|
|
sendDisabled: null,
|
|
answerText: "答案",
|
|
answerBlocks: ["答案"],
|
|
reasoningText: null,
|
|
reasoningBlocks: [],
|
|
questionMatched: true,
|
|
candidateAnswerCount: 1,
|
|
candidateReasoningCount: 0,
|
|
citationLinks: [],
|
|
panelCitationLinks: [],
|
|
inlineCitationCandidateLinks: [],
|
|
searchResultLinks: [],
|
|
signature: "sig",
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe("kimi adapter helpers", () => {
|
|
it("unwraps Kimi redirect URLs before storing source items", () => {
|
|
expect(normalizeUrl("https://www.kimi.com/redirect?url=https%3A%2F%2Fexample.com%2Fsource%23ref")).toBe(
|
|
"https://example.com/source",
|
|
);
|
|
|
|
expect(buildSourceItem({
|
|
url: "https://www.kimi.com/redirect?target=https%3A%2F%2Fsource.example.com%2Fnews%3Fid%3D1",
|
|
title: "搜索结果标题",
|
|
text: null,
|
|
siteName: "来源站点",
|
|
})).toMatchObject({
|
|
url: "https://source.example.com/news?id=1",
|
|
normalized_url: "https://source.example.com/news?id=1",
|
|
title: "搜索结果标题",
|
|
site_name: "来源站点",
|
|
host: "source.example.com",
|
|
});
|
|
});
|
|
|
|
it("uses search web results as citation sources and footer references as content citation candidates", () => {
|
|
const classified = classifyKimiSources(buildSnapshot({
|
|
searchResultLinks: [
|
|
{
|
|
url: "https://search.example.com/a",
|
|
title: "搜索网页 A",
|
|
text: "搜索网页 A",
|
|
siteName: "搜索站点",
|
|
},
|
|
],
|
|
panelCitationLinks: [
|
|
{
|
|
url: "https://content.example.com/cited",
|
|
title: "页尾引用文章",
|
|
text: "页尾引用文章",
|
|
siteName: "内容站点",
|
|
},
|
|
],
|
|
inlineCitationCandidateLinks: [
|
|
{
|
|
url: "https://content.example.com/site",
|
|
title: null,
|
|
text: "内容站点",
|
|
siteName: "内容站点",
|
|
},
|
|
],
|
|
}));
|
|
|
|
expect(classified.citations).toHaveLength(1);
|
|
expect(classified.citations[0]?.url).toBe("https://search.example.com/a");
|
|
expect(classified.searchResults[0]?.url).toBe("https://search.example.com/a");
|
|
expect(classified.panelCitations[0]?.url).toBe("https://content.example.com/cited");
|
|
expect(classified.inlineCitationCandidates.map((item) => item.url)).toEqual([
|
|
"https://content.example.com/cited",
|
|
"https://content.example.com/site",
|
|
]);
|
|
});
|
|
|
|
it("falls back to footer references as citation sources when no search web results are visible", () => {
|
|
const classified = classifyKimiSources(buildSnapshot({
|
|
panelCitationLinks: [
|
|
{
|
|
url: "https://content.example.com/cited",
|
|
title: "页尾引用文章",
|
|
text: "页尾引用文章",
|
|
siteName: "内容站点",
|
|
},
|
|
],
|
|
}));
|
|
|
|
expect(classified.searchResults).toHaveLength(0);
|
|
expect(classified.citations).toHaveLength(1);
|
|
expect(classified.citations[0]?.url).toBe("https://content.example.com/cited");
|
|
});
|
|
|
|
it("keeps the answer text from the content snapshot when merging side-panel sources", () => {
|
|
const merged = mergeKimiSourceLinksIntoContentSnapshot(
|
|
buildSnapshot({
|
|
answerText: "真实回答正文",
|
|
answerBlocks: ["真实回答正文"],
|
|
}),
|
|
buildSnapshot({
|
|
answerText: "搜索网页 48\nhttps://example.com/a 很长的侧栏文本",
|
|
answerBlocks: ["搜索网页 48\nhttps://example.com/a 很长的侧栏文本"],
|
|
searchResultLinks: [
|
|
{
|
|
url: "https://example.com/a",
|
|
title: "搜索结果 A",
|
|
text: "搜索结果 A",
|
|
siteName: "Example",
|
|
},
|
|
],
|
|
}),
|
|
);
|
|
|
|
expect(merged.answerText).toBe("真实回答正文");
|
|
expect(merged.answerBlocks).toEqual(["真实回答正文"]);
|
|
expect(merged.searchResultLinks).toHaveLength(1);
|
|
expect(merged.searchResultLinks[0]?.url).toBe("https://example.com/a");
|
|
});
|
|
});
|