import { describe, expect, it } from "vitest"; import { __kimiTestUtils } from "./kimi"; const { buildSourceItem, classifyKimiSources, mergeKimiSourceLinksIntoContentSnapshot, normalizeUrl, } = __kimiTestUtils; function buildSnapshot(overrides: Partial[0]>): Parameters[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"); }); });