Skip to content

Commit c7f7a7f

Browse files
committed
Uplift of #29263 (squashed) to beta
1 parent 10b77f0 commit c7f7a7f

File tree

2 files changed

+83
-8
lines changed

2 files changed

+83
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/* Copyright (c) 2025 The Brave Authors. All rights reserved.
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
4+
* You can obtain one at https://mozilla.org/MPL/2.0/. */
5+
6+
import * as React from 'react'
7+
import * as Mojom from '../../../common/mojom'
8+
import { render } from '@testing-library/react'
9+
import '@testing-library/jest-dom'
10+
import { useUntrustedConversationContext }
11+
from '../../untrusted_conversation_context'
12+
import ConversationEntries from '.'
13+
14+
const assistantResponseMock = jest.fn(() => <div />)
15+
16+
jest.mock('../assistant_response', () => ({
17+
__esModule: true,
18+
default: (props: any) => {
19+
assistantResponseMock(props)
20+
return <div />
21+
}
22+
}))
23+
24+
jest.mock('../../untrusted_conversation_context', () => ({
25+
useUntrustedConversationContext: jest.fn()
26+
}))
27+
28+
describe('ConversationEntries allowedLinks per response', () => {
29+
beforeEach(() => {
30+
assistantResponseMock.mockClear()
31+
32+
const turn1 = {
33+
characterType: Mojom.CharacterType.ASSISTANT,
34+
events: [
35+
{ completionEvent: { completion: 'Response 1' } },
36+
{
37+
sourcesEvent: {
38+
sources: [{ url: { url: 'https://a.com' } }]
39+
}
40+
}
41+
]
42+
}
43+
44+
const turn2 = {
45+
characterType: Mojom.CharacterType.ASSISTANT,
46+
events: [
47+
{ completionEvent: { completion: 'Response 2' } },
48+
{
49+
sourcesEvent: {
50+
sources: [{ url: { url: 'https://b.com' } }]
51+
}
52+
}
53+
]
54+
}
55+
56+
;(useUntrustedConversationContext as jest.Mock).mockReturnValue({
57+
conversationHistory: [turn1, turn2],
58+
isGenerating: false,
59+
isMobile: false,
60+
isLeoModel: true,
61+
allModels: [],
62+
canSubmitUserEntries: true,
63+
conversationHandler: null,
64+
trimmedTokens: 0,
65+
totalTokens: 100,
66+
contentUsedPercentage: 100
67+
})
68+
})
69+
70+
it('passes correct allowedLinks to each AssistantResponse', () => {
71+
render(<ConversationEntries />)
72+
expect(assistantResponseMock).toHaveBeenCalledTimes(2)
73+
expect(assistantResponseMock.mock.calls[0][0].allowedLinks).toEqual(['https://a.com'])
74+
expect(assistantResponseMock.mock.calls[1][0].allowedLinks).toEqual(['https://b.com'])
75+
})
76+
})

components/ai_chat/resources/untrusted_conversation_frame/components/conversation_entries/index.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,6 @@ function ConversationEntries() {
5858
return event?.completionEvent?.completion ?? ''
5959
}
6060

61-
const allAllowedLinks: string[] = conversationContext.conversationHistory
62-
.flatMap(turn =>
63-
turn.events?.flatMap(event =>
64-
event.sourcesEvent?.sources?.map(source => source.url.url) || []
65-
) || []
66-
)
67-
6861
return (
6962
<>
7063
<div>
@@ -85,6 +78,12 @@ function ConversationEntries() {
8578
const showEditIndicator = !showEditInput && !!turn.edits?.length
8679
const latestEdit = turn.edits?.at(-1)
8780
const latestTurn = latestEdit ?? turn
81+
const allowedLinksForTurn: string[] =
82+
latestTurn.events?.flatMap(event =>
83+
event.sourcesEvent?.sources?.map(
84+
source => source.url.url
85+
) || []
86+
) || []
8887
const latestTurnText = isAIAssistant
8988
? getCompletion(latestTurn)
9089
: latestTurn.text
@@ -157,7 +156,7 @@ function ConversationEntries() {
157156
<AssistantResponse
158157
entry={latestTurn}
159158
isEntryInProgress={isEntryInProgress}
160-
allowedLinks={allAllowedLinks}
159+
allowedLinks={allowedLinksForTurn}
161160
isLeoModel={conversationContext.isLeoModel}
162161
/>
163162
)}

0 commit comments

Comments
 (0)