Files
geo/apps/desktop-client/src/main/adapters/kimi.test.ts
T

171 lines
5.2 KiB
TypeScript
Raw Normal View History

import { describe, expect, it } from 'vitest'
import { __kimiTestUtils } from './kimi'
const {
buildSourceItem,
classifyKimiSources,
isKimiAnswerComplete,
isKimiPromotionalAnswerNoise,
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: [],
capacityNotice: null,
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')
})
it('rejects Kimi K2.6 marketing copy as an answer', () => {
const promotionalText = [
'Kimi K2.6,已就位!',
'Coding、Agent 集群、Kimi Claw 同步升级',
'Agent 集群,升级了',
'多技能调用,多产物类型一次性交付',
'Kimi Claw 已就位!',
'一键部署 OpenClawKimi 24小时为你干活',
].join('\n')
expect(isKimiPromotionalAnswerNoise(promotionalText)).toBe(true)
expect(
isKimiAnswerComplete(
buildSnapshot({
answerText: promotionalText,
answerBlocks: [promotionalText],
}),
),
).toBe(false)
})
})