import { describe, expect, it } from 'vitest' import { __doubaoTestUtils } from './doubao' const { buildSourceItem, dedupeSourceItems, isNonCitationAssetDomain, isNonCitationAssetUrl, parseDoubaoStreamBody, resolveDoubaoSubmissionAnswer, } = __doubaoTestUtils describe('doubao adapter helpers', () => { it('filters byteimg and bytednsdoc asset CDN links from source items', () => { expect(isNonCitationAssetDomain('p3-spider-image-sign.byteimg.com')).toBe(true) expect(isNonCitationAssetDomain('lf3-static.bytednsdoc.com')).toBe(true) expect(isNonCitationAssetUrl('https://p11-spider-image-sign.byteimg.com/obj/logo.png')).toBe( true, ) expect(isNonCitationAssetUrl('https://m.sohu.com/a/1012750625_122649842/')).toBe(false) expect( buildSourceItem({ url: 'https://p3-spider-image-sign.byteimg.com/img/logo.jpeg', title: 'logo', site_name: 'byteimg.com', }), ).toBeNull() expect( buildSourceItem({ url: 'https://example.com/article', title: '真实来源', }), ).toMatchObject({ url: 'https://example.com/article', host: 'example.com', }) }) it('dedupes and drops asset CDN links parsed from Doubao streams', () => { const body = [ 'event: STREAM_CHUNK', 'data: {"references":[{"url":"https://p11-spider-image-sign.byteimg.com/logo.jpeg","title":"logo"},{"url":"https://m.sohu.com/a/1012750625_122649842/","title":"真实来源"}],"text_block":{"text":"回答"}}', '', '', ].join('\n') const summary = parseDoubaoStreamBody(body) expect(summary.search_results).toHaveLength(1) expect(summary.search_results[0]?.url).toBe('https://m.sohu.com/a/1012750625_122649842/') expect( dedupeSourceItems([ { url: 'https://static.bytednsdoc.com/logo.png', normalized_url: 'https://static.bytednsdoc.com/logo.png', }, { url: 'https://example.com/a', normalized_url: 'https://example.com/a' }, ]), ).toHaveLength(1) }) it('uses thinking-chain reference metadata to fill unknown Doubao source titles', () => { const body = [ 'event: STREAM_CHUNK', 'data: {"references":[{"url":"https://example.com/report","title":"unkown"}],"thinking":{"references":[{"url":"https://example.com/report#section","title":"思考链路里的真实标题","site_name":"示例站点"}]},"text_block":{"text":"回答"}}', '', '', ].join('\n') const summary = parseDoubaoStreamBody(body) expect(summary.search_results).toHaveLength(1) expect(summary.search_results[0]?.url).toBe('https://example.com/report') expect(summary.search_results[0]?.title).toBe('思考链路里的真实标题') expect(summary.search_results[0]?.site_name).toBe('示例站点') }) it('unwraps Doubao redirect URLs before storing citation sources', () => { const item = buildSourceItem({ url: 'https://www.doubao.com/link?target=https%3A%2F%2Fexample.com%2Fsource%23ref', title: 'unknown', }) expect(item).toMatchObject({ url: 'https://example.com/source', normalized_url: 'https://example.com/source', host: 'example.com', title: null, }) }) it('parses Doubao answer deltas and source cards from the completion SSE stream', () => { const sourceChunkPayload = { patch_op: [ { patch_value: { content_block: [ { block_type: 10025, content: { search_query_result_block: { results: [ { text_card: { url: 'https://k.sina.cn/article_3244012052_c15bb21400101k0hg.html', title: '2026年合肥全屋定制品牌综合实力排名出炉', sitename: '新浪', logo_url: 'https://p11-spider-image-sign.byteimg.com/logo.jpeg', }, }, ], }, }, }, ], }, }, ], } const body = [ 'event: SSE_ACK', 'data: {"ack_client_meta":{"conversation_id":"38427686224603138","section_id":"38427686224603394"}}', '', 'event: FULL_MSG_NOTIFY', 'data: {"message":{"content":"用户问题 echo,不是答案","conversation_id":"38427686224603138"}}', '', 'event: STREAM_CHUNK', `data: ${JSON.stringify(sourceChunkPayload)}`, '', 'event: CHUNK_DELTA', 'data: {"text":"直接给你"}', '', 'event: CHUNK_DELTA', 'data: {"text":"一份清单。"}', '', 'event: SSE_REPLY_END', 'data: {"end_type":2,"answer_finish_attr":{"has_suggest":true}}', '', '', ].join('\n') const summary = parseDoubaoStreamBody(body) expect(summary.answer).toBe('直接给你一份清单。') expect(summary.conversation_id).toBe('38427686224603138') expect(summary.full_message_event_count).toBe(1) expect(summary.reply_end_event_count).toBe(1) expect(summary.answer_finish_event_count).toBe(1) expect(summary.search_results).toHaveLength(1) expect(summary.search_results[0]).toMatchObject({ url: 'https://k.sina.cn/article_3244012052_c15bb21400101k0hg.html', title: '2026年合肥全屋定制品牌综合实力排名出炉', site_name: '新浪', host: 'k.sina.cn', }) }) it('repairs mixed Doubao mojibake fragments before returning the SSE answer', () => { const body = [ 'event: CHUNK_DELTA', 'data: {"text":"需要合肥地区全屋定制推荐,"}', '', 'event: CHUNK_DELTA', 'data: {"text":"综合考量性价比、口碑服务等因素。2000㎡展厅,核验批号。"}', '', 'event: SSE_REPLY_END', 'data: {"end_type":2,"answer_finish_attr":{"has_suggest":true}}', '', '', ].join('\n') const summary = parseDoubaoStreamBody(body) expect(summary.answer).toBe( '需要合肥地区全屋定制推荐,综合考量性价比、口碑服务等因素。2000㎡展厅,核验批号。', ) expect(summary.answer).not.toMatch(/[åæèéäãï][\u0080-\u00ff\u02c0-\u02ff\u2000-\u20ff]/) expect(resolveDoubaoSubmissionAnswer({ answer: summary.answer })).toEqual({ answer: '需要合肥地区全屋定制推荐,综合考量性价比、口碑服务等因素。2000㎡展厅,核验批号。', source: 'sse', }) }) it('does not treat FULL_MSG_NOTIFY user echo as the Doubao answer', () => { const body = [ 'event: FULL_MSG_NOTIFY', 'data: {"message":{"content":"合肥全屋定制哪家好"}}', '', 'event: SSE_REPLY_END', 'data: {"end_type":2,"answer_finish_attr":{"has_suggest":true}}', '', '', ].join('\n') const summary = parseDoubaoStreamBody(body) expect(summary.answer).toBeNull() expect(summary.full_message_event_count).toBe(1) expect(summary.answer_finish_event_count).toBe(1) }) it('submits only SSE answer text, without reasoning fallback', () => { expect( resolveDoubaoSubmissionAnswer({ answer: 'SSE 正文答案', }), ).toEqual({ answer: 'SSE 正文答案', source: 'sse', }) }) it('does not submit a success answer when the SSE stream has no answer text', () => { expect( resolveDoubaoSubmissionAnswer({ answer: null, }), ).toEqual({ answer: null, source: null, }) }) })