diff --git a/.github/actions/e2e-quantic/action.yml b/.github/actions/e2e-quantic/action.yml index c2ce1bce83d..bfe86b28c62 100644 --- a/.github/actions/e2e-quantic/action.yml +++ b/.github/actions/e2e-quantic/action.yml @@ -15,6 +15,8 @@ runs: with: path: packages/quantic/cypress/plugins/config key: quantic-cypress-config-${{ github.sha }} + - run: npx cypress install + shell: bash - uses: cypress-io/github-action@v5 name: Run Cypress with: diff --git a/packages/atomic/cypress/e2e/generated-answer-selectors.ts b/packages/atomic/cypress/e2e/generated-answer-selectors.ts index 485f33ad164..529a7622275 100644 --- a/packages/atomic/cypress/e2e/generated-answer-selectors.ts +++ b/packages/atomic/cypress/e2e/generated-answer-selectors.ts @@ -1,4 +1,4 @@ -import {GeneratedAnswerFeedbackV2} from '@coveo/headless'; +import {GeneratedAnswerFeedback} from '@coveo/headless'; export const generatedAnswerComponent = 'atomic-generated-answer'; export const feedbackModal = 'atomic-generated-answer-feedback-modal'; @@ -57,7 +57,7 @@ export const feedbackModalSelectors = { feedbackModalSelectors.atomicModal().find('[part="modal-footer"]'), other: () => feedbackModalSelectors.atomicModal().find('.other'), feedbackOption: ( - feedback: keyof GeneratedAnswerFeedbackV2, + feedback: keyof GeneratedAnswerFeedback, optionText: 'No' | 'Yes' | 'Not sure' ) => feedbackModalSelectors diff --git a/packages/atomic/src/components/common/generated-answer/atomic-generated-answer-feedback/atomic-generated-answer-feedback-modal.tsx b/packages/atomic/src/components/common/generated-answer/atomic-generated-answer-feedback/atomic-generated-answer-feedback-modal.tsx index f7ba34d0d7a..70fea6acc3f 100644 --- a/packages/atomic/src/components/common/generated-answer/atomic-generated-answer-feedback/atomic-generated-answer-feedback-modal.tsx +++ b/packages/atomic/src/components/common/generated-answer/atomic-generated-answer-feedback/atomic-generated-answer-feedback-modal.tsx @@ -1,6 +1,6 @@ import { GeneratedAnswer, - GeneratedAnswerFeedbackV2, + GeneratedAnswerFeedback, GeneratedAnswerFeedbackOption, } from '@coveo/headless'; import { @@ -55,7 +55,7 @@ export class AtomicGeneratedAnswerFeedbackModal @Prop({reflect: true, mutable: true}) helpful = false; @State() public error!: Error; - @State() private currentAnswer: Partial = + @State() private currentAnswer: Partial = this.getInitialAnswerState(); @State() feedbackSubmitted: boolean = false; @State() answerEvaluationRequired: boolean = false; @@ -78,7 +78,7 @@ export class AtomicGeneratedAnswerFeedbackModal private static options: { localeKey: string; - correspondingAnswer: keyof GeneratedAnswerFeedbackV2; + correspondingAnswer: keyof GeneratedAnswerFeedback; }[] = [ { localeKey: 'feedback-correct-topic', @@ -98,7 +98,7 @@ export class AtomicGeneratedAnswerFeedbackModal }, ]; - private getInitialAnswerState(): Partial { + private getInitialAnswerState(): Partial { return { documented: undefined, correctTopic: undefined, @@ -132,7 +132,7 @@ export class AtomicGeneratedAnswerFeedbackModal private updateBreakpoints = once(() => updateBreakpoints(this.host)); private setCurrentAnswer( - key: keyof GeneratedAnswerFeedbackV2, + key: keyof GeneratedAnswerFeedback, value: GeneratedAnswerFeedbackOption | string ) { this.currentAnswer = { @@ -142,8 +142,8 @@ export class AtomicGeneratedAnswerFeedbackModal } public sendFeedback() { - const feedback: GeneratedAnswerFeedbackV2 = { - ...(this.currentAnswer as GeneratedAnswerFeedbackV2), + const feedback: GeneratedAnswerFeedback = { + ...(this.currentAnswer as GeneratedAnswerFeedback), helpful: this.helpful, }; this.generatedAnswer.sendFeedback(feedback); @@ -194,7 +194,7 @@ export class AtomicGeneratedAnswerFeedbackModal private renderFeedbackOption( option: GeneratedAnswerFeedbackOption, - correspondingAnswer: keyof GeneratedAnswerFeedbackV2 + correspondingAnswer: keyof GeneratedAnswerFeedback ) { const buttonClasses = [ 'min-w-20', @@ -229,7 +229,7 @@ export class AtomicGeneratedAnswerFeedbackModal private renderAnswerEvaluation( label: string, - correspondingAnswer: keyof GeneratedAnswerFeedbackV2 + correspondingAnswer: keyof GeneratedAnswerFeedback ) { const labelClasses = ['text-error-red', 'text-sm', 'hidden']; const isRequired = diff --git a/packages/headless/src/controllers/core/generated-answer/headless-core-generated-answer.test.ts b/packages/headless/src/controllers/core/generated-answer/headless-core-generated-answer.test.ts index 0c2c88440f4..b966fe8ccb3 100644 --- a/packages/headless/src/controllers/core/generated-answer/headless-core-generated-answer.test.ts +++ b/packages/headless/src/controllers/core/generated-answer/headless-core-generated-answer.test.ts @@ -14,7 +14,6 @@ import { generatedAnswerAnalyticsClient, logCopyGeneratedAnswer, logDislikeGeneratedAnswer, - logGeneratedAnswerDetailedFeedback, logGeneratedAnswerFeedback, logGeneratedAnswerHideAnswers, logGeneratedAnswerShowAnswers, @@ -23,7 +22,7 @@ import { logOpenGeneratedAnswerSource, logGeneratedAnswerExpand, logGeneratedAnswerCollapse, - GeneratedAnswerFeedbackV2, + GeneratedAnswerFeedback, } from '../../../features/generated-answer/generated-answer-analytics-actions'; import {generatedAnswerReducer} from '../../../features/generated-answer/generated-answer-slice'; import { @@ -129,15 +128,8 @@ describe('generated answer', () => { expect(closeGeneratedAnswerFeedbackModal).toHaveBeenCalled(); }); - it('#sendFeedback dispatches the V1 actions', () => { - const exampleFeedback = 'notAccurate'; - generatedAnswer.sendFeedback(exampleFeedback); - expect(sendGeneratedAnswerFeedback).toHaveBeenCalled(); - expect(logGeneratedAnswerFeedback).toHaveBeenCalledWith(exampleFeedback); - }); - it('#sendFeedback dispatches the V2 actions', () => { - const exampleFeedback: GeneratedAnswerFeedbackV2 = { + const exampleFeedback: GeneratedAnswerFeedback = { helpful: true, documented: 'yes', correctTopic: 'no', @@ -149,15 +141,6 @@ describe('generated answer', () => { expect(logGeneratedAnswerFeedback).toHaveBeenCalledWith(exampleFeedback); }); - it('#sendDetailedFeedback dispatches the right actions', () => { - const exampleDetails = 'Example details'; - generatedAnswer.sendDetailedFeedback(exampleDetails); - expect(sendGeneratedAnswerFeedback).toHaveBeenCalled(); - expect(logGeneratedAnswerDetailedFeedback).toHaveBeenCalledWith( - exampleDetails - ); - }); - it('#logCitationClick dispatches analytics action', () => { const testCitation = buildMockCitation(); generatedAnswer.logCitationClick(testCitation.id); diff --git a/packages/headless/src/controllers/core/generated-answer/headless-core-generated-answer.ts b/packages/headless/src/controllers/core/generated-answer/headless-core-generated-answer.ts index 0bb9a80e574..2290ec32a9f 100644 --- a/packages/headless/src/controllers/core/generated-answer/headless-core-generated-answer.ts +++ b/packages/headless/src/controllers/core/generated-answer/headless-core-generated-answer.ts @@ -16,10 +16,7 @@ import { expandGeneratedAnswer, collapseGeneratedAnswer, } from '../../../features/generated-answer/generated-answer-actions'; -import { - GeneratedAnswerFeedback, - GeneratedAnswerFeedbackV2, -} from '../../../features/generated-answer/generated-answer-analytics-actions'; +import {GeneratedAnswerFeedback} from '../../../features/generated-answer/generated-answer-analytics-actions'; import {generatedAnswerReducer as generatedAnswer} from '../../../features/generated-answer/generated-answer-slice'; import {GeneratedAnswerState} from '../../../features/generated-answer/generated-answer-state'; import {GeneratedResponseFormat} from '../../../features/generated-answer/generated-response-format'; @@ -74,15 +71,7 @@ export interface GeneratedAnswer extends Controller { * Sends feedback about why the generated answer was not relevant. * @param feedback - The feedback that the end user wishes to send. */ - // TODO: Update feedback type, to change in TODO: SFINT-5585 - sendFeedback( - feedback: GeneratedAnswerFeedback | GeneratedAnswerFeedbackV2 - ): void; - /** - * Sends detailed feedback about why the generated answer was not relevant. - * @param details - Details on why the generated answer was not relevant. - */ - sendDetailedFeedback(details: string): void; + sendFeedback(feedback: GeneratedAnswerFeedback): void; /** * Logs a custom event indicating a cited source link was clicked. * @param id - The ID of the clicked citation. @@ -120,9 +109,8 @@ export interface GeneratedAnswerAnalyticsClient { logLikeGeneratedAnswer: () => CustomAction; logDislikeGeneratedAnswer: () => CustomAction; logGeneratedAnswerFeedback: ( - feedback: GeneratedAnswerFeedback | GeneratedAnswerFeedbackV2 + feedback: GeneratedAnswerFeedback ) => CustomAction; - logGeneratedAnswerDetailedFeedback: (details: string) => CustomAction; logOpenGeneratedAnswerSource: (citationId: string) => CustomAction; logHoverCitation: ( citationId: string, @@ -240,11 +228,6 @@ export function buildCoreGeneratedAnswer( dispatch(sendGeneratedAnswerFeedback()); }, - sendDetailedFeedback(details) { - dispatch(analyticsClient.logGeneratedAnswerDetailedFeedback(details)); - dispatch(sendGeneratedAnswerFeedback()); - }, - logCitationClick(citationId: string) { dispatch(analyticsClient.logOpenGeneratedAnswerSource(citationId)); }, diff --git a/packages/headless/src/controllers/core/generated-answer/headless-searchapi-generated-answer.test.ts b/packages/headless/src/controllers/core/generated-answer/headless-searchapi-generated-answer.test.ts index c5e374207d5..348b0dfa5d1 100644 --- a/packages/headless/src/controllers/core/generated-answer/headless-searchapi-generated-answer.test.ts +++ b/packages/headless/src/controllers/core/generated-answer/headless-searchapi-generated-answer.test.ts @@ -124,26 +124,24 @@ describe('searchapi-generated-answer', () => { expect(closeGeneratedAnswerFeedbackModal).toHaveBeenCalled(); }); - it('dispatches a send feedback action', () => { + it('dispatches a sendFeedback action', () => { const generatedAnswer = createGeneratedAnswer(); - const feedback: GeneratedAnswerFeedback = 'harmful'; + const feedback: GeneratedAnswerFeedback = { + readable: 'unknown', + correctTopic: 'unknown', + documented: 'yes', + hallucinationFree: 'no', + helpful: false, + details: 'some details', + }; generatedAnswer.sendFeedback(feedback); + expect( generatedAnswerAnalyticsClient.logGeneratedAnswerFeedback ).toHaveBeenCalledWith(feedback); expect(sendGeneratedAnswerFeedback).toHaveBeenCalledTimes(1); }); - it('dispatches a send detailed feedback action', () => { - const generatedAnswer = createGeneratedAnswer(); - const details = 'details'; - generatedAnswer.sendDetailedFeedback(details); - expect( - generatedAnswerAnalyticsClient.logGeneratedAnswerDetailedFeedback - ).toHaveBeenCalledWith(details); - expect(sendGeneratedAnswerFeedback).toHaveBeenCalledTimes(1); - }); - it('dispatches a log citation click action', () => { const generatedAnswer = createGeneratedAnswer(); const citationId = 'citationId'; diff --git a/packages/headless/src/controllers/knowledge/generated-answer/headless-answerapi-generated-answer.test.ts b/packages/headless/src/controllers/knowledge/generated-answer/headless-answerapi-generated-answer.test.ts index dfc4695b63a..1eeca981a84 100644 --- a/packages/headless/src/controllers/knowledge/generated-answer/headless-answerapi-generated-answer.test.ts +++ b/packages/headless/src/controllers/knowledge/generated-answer/headless-answerapi-generated-answer.test.ts @@ -11,7 +11,7 @@ import { } from '../../../features/generated-answer/generated-answer-actions'; import { generatedAnswerAnalyticsClient, - GeneratedAnswerFeedbackV2, + GeneratedAnswerFeedback, } from '../../../features/generated-answer/generated-answer-analytics-actions'; import {getGeneratedAnswerInitialState} from '../../../features/generated-answer/generated-answer-state'; import {queryReducer} from '../../../features/query/query-slice'; @@ -149,7 +149,7 @@ describe('knowledge-generated-answer', () => { query: {q: 'this est une question', enableQuerySyntax: false}, }); const generatedAnswer = createGeneratedAnswer(); - const feedback: GeneratedAnswerFeedbackV2 = { + const feedback: GeneratedAnswerFeedback = { readable: 'unknown', correctTopic: 'unknown', documented: 'yes', diff --git a/packages/headless/src/controllers/knowledge/generated-answer/headless-answerapi-generated-answer.ts b/packages/headless/src/controllers/knowledge/generated-answer/headless-answerapi-generated-answer.ts index 79f5c47a039..512a1e51b47 100644 --- a/packages/headless/src/controllers/knowledge/generated-answer/headless-answerapi-generated-answer.ts +++ b/packages/headless/src/controllers/knowledge/generated-answer/headless-answerapi-generated-answer.ts @@ -16,7 +16,7 @@ import { sendGeneratedAnswerFeedback, updateAnswerConfigurationId, } from '../../../features/generated-answer/generated-answer-actions'; -import {GeneratedAnswerFeedbackV2} from '../../../features/generated-answer/generated-answer-analytics-actions'; +import {GeneratedAnswerFeedback} from '../../../features/generated-answer/generated-answer-analytics-actions'; import {queryReducer as query} from '../../../features/query/query-slice'; import { GeneratedAnswerSection, @@ -41,7 +41,7 @@ export interface AnswerApiGeneratedAnswer * Sends feedback about why the generated answer was not relevant. * @param feedback - The feedback that the end user wishes to send. */ - sendFeedback(feedback: GeneratedAnswerFeedbackV2): void; + sendFeedback(feedback: GeneratedAnswerFeedback): void; } interface AnswerApiGeneratedAnswerProps extends GeneratedAnswerProps {} @@ -50,7 +50,7 @@ export interface SearchAPIGeneratedAnswerAnalyticsClient extends GeneratedAnswerAnalyticsClient {} interface ParseEvaluationArgumentsParams { - feedback: GeneratedAnswerFeedbackV2; + feedback: GeneratedAnswerFeedback; answerApiState: GeneratedAnswerStream; query: string; } diff --git a/packages/headless/src/features/generated-answer/__snapshots__/generated-answer-analytics-actions.test.ts.snap b/packages/headless/src/features/generated-answer/__snapshots__/generated-answer-analytics-actions.test.ts.snap index 6354d5a9fef..849fa2e0824 100644 --- a/packages/headless/src/features/generated-answer/__snapshots__/generated-answer-analytics-actions.test.ts.snap +++ b/packages/headless/src/features/generated-answer/__snapshots__/generated-answer-analytics-actions.test.ts.snap @@ -39,8 +39,6 @@ exports[`generated answer analytics actions when analyticsMode is \`next\` shoul ] `; -exports[`generated answer analytics actions when analyticsMode is \`next\` should log #logGeneratedAnswerDetailedFeedback with the right payload 1`] = `undefined`; - exports[`generated answer analytics actions when analyticsMode is \`next\` should log #logGeneratedAnswerExpand with the right payload 1`] = ` [ "Qna.AnswerAction", diff --git a/packages/headless/src/features/generated-answer/__snapshots__/generated-answer-insight-analytics-actions.test.ts.snap b/packages/headless/src/features/generated-answer/__snapshots__/generated-answer-insight-analytics-actions.test.ts.snap index 7fc303bedb1..971814fc8cb 100644 --- a/packages/headless/src/features/generated-answer/__snapshots__/generated-answer-insight-analytics-actions.test.ts.snap +++ b/packages/headless/src/features/generated-answer/__snapshots__/generated-answer-insight-analytics-actions.test.ts.snap @@ -39,8 +39,6 @@ exports[`generated answer insight analytics actions when analyticsMode is \`next ] `; -exports[`generated answer insight analytics actions when analyticsMode is \`next\` should log #logGeneratedAnswerDetailedFeedback with the right payload 1`] = `undefined`; - exports[`generated answer insight analytics actions when analyticsMode is \`next\` should log #logGeneratedAnswerExpand with the right payload 1`] = ` [ "Qna.AnswerAction", diff --git a/packages/headless/src/features/generated-answer/generated-answer-analytics-actions.test.ts b/packages/headless/src/features/generated-answer/generated-answer-analytics-actions.test.ts index 2c4a01d0731..3d92fda6f8b 100644 --- a/packages/headless/src/features/generated-answer/generated-answer-analytics-actions.test.ts +++ b/packages/headless/src/features/generated-answer/generated-answer-analytics-actions.test.ts @@ -12,7 +12,6 @@ import {getConfigurationInitialState} from '../configuration/configuration-state import { logCopyGeneratedAnswer, logDislikeGeneratedAnswer, - logGeneratedAnswerDetailedFeedback, logGeneratedAnswerFeedback, logGeneratedAnswerHideAnswers, logGeneratedAnswerShowAnswers, @@ -24,7 +23,7 @@ import { logRetryGeneratedAnswer, logGeneratedAnswerExpand, logGeneratedAnswerCollapse, - GeneratedAnswerFeedbackV2, + GeneratedAnswerFeedback, } from './generated-answer-analytics-actions'; import {getGeneratedAnswerInitialState} from './generated-answer-state'; import {generatedAnswerStyle} from './generated-response-format'; @@ -111,8 +110,7 @@ jest.mock('coveo.analytics', () => { }; }); -const exampleFeedback = 'irrelevant'; -const exampleFeedbackV2: GeneratedAnswerFeedbackV2 = { +const exampleFeedback: GeneratedAnswerFeedback = { helpful: true, documented: 'yes', correctTopic: 'no', @@ -121,7 +119,6 @@ const exampleFeedbackV2: GeneratedAnswerFeedbackV2 = { }; const exampleGenerativeQuestionAnsweringId = '123'; const exampleSearchUid = '456'; -const exampleDetails = 'example details'; const exampleCitation: GeneratedAnswerCitation = { id: 'some-citation-id', @@ -271,26 +268,8 @@ describe('generated answer analytics actions', () => { expect(mockLogFunction).toHaveBeenCalledTimes(1); }); - it('should log #logGeneratedAnswerFeedback with V1 payload', async () => { - await logGeneratedAnswerFeedback(exampleFeedback)()( - engine.dispatch, - () => engine.state, - {} as ThunkExtraArguments - ); - - const mockToUse = mockMakeGeneratedAnswerFeedbackSubmit; - const expectedMetadata = { - generativeQuestionAnsweringId: exampleGenerativeQuestionAnsweringId, - reason: exampleFeedback, - }; - - expect(mockToUse).toHaveBeenCalledTimes(1); - expect(mockToUse).toHaveBeenCalledWith(expectedMetadata); - expect(mockLogFunction).toHaveBeenCalledTimes(1); - }); - it('should log #logGeneratedAnswerFeedback with V2 payload', async () => { - await logGeneratedAnswerFeedback(exampleFeedbackV2)()( + await logGeneratedAnswerFeedback(exampleFeedback)()( engine.dispatch, () => engine.state, {} as ThunkExtraArguments @@ -299,26 +278,7 @@ describe('generated answer analytics actions', () => { const mockToUse = mockMakeGeneratedAnswerFeedbackSubmitV2; const expectedMetadata = { generativeQuestionAnsweringId: exampleGenerativeQuestionAnsweringId, - ...exampleFeedbackV2, - }; - - expect(mockToUse).toHaveBeenCalledTimes(1); - expect(mockToUse).toHaveBeenCalledWith(expectedMetadata); - expect(mockLogFunction).toHaveBeenCalledTimes(1); - }); - - it('should log #logGeneratedAnswerDetailedFeedback with the right payload', async () => { - await logGeneratedAnswerDetailedFeedback(exampleDetails)()( - engine.dispatch, - () => engine.state, - {} as ThunkExtraArguments - ); - - const mockToUse = mockMakeGeneratedAnswerFeedbackSubmit; - const expectedMetadata = { - generativeQuestionAnsweringId: exampleGenerativeQuestionAnsweringId, - reason: 'other', - details: exampleDetails, + ...exampleFeedback, }; expect(mockToUse).toHaveBeenCalledTimes(1); @@ -524,19 +484,8 @@ describe('generated answer analytics actions', () => { expect(emit.mock.calls[0]).toMatchSnapshot(); }); - it('should log #logGeneratedAnswerDetailedFeedback with the right payload', async () => { - await logGeneratedAnswerDetailedFeedback(exampleDetails)()( - engine.dispatch, - () => engine.state, - {} as ThunkExtraArguments - ); - - expect(emit).toHaveBeenCalledTimes(0); - expect(emit.mock.calls[0]).toMatchSnapshot(); - }); - it('should log #logGeneratedAnswerFeedback with the right payload', async () => { - await logGeneratedAnswerFeedback(exampleFeedbackV2)()( + await logGeneratedAnswerFeedback(exampleFeedback)()( engine.dispatch, () => engine.state, {} as ThunkExtraArguments diff --git a/packages/headless/src/features/generated-answer/generated-answer-analytics-actions.ts b/packages/headless/src/features/generated-answer/generated-answer-analytics-actions.ts index 3fca657482e..ae148097e09 100644 --- a/packages/headless/src/features/generated-answer/generated-answer-analytics-actions.ts +++ b/packages/headless/src/features/generated-answer/generated-answer-analytics-actions.ts @@ -12,15 +12,9 @@ import { } from './generated-answer-selectors'; import {GeneratedResponseFormat} from './generated-response-format'; -export type GeneratedAnswerFeedback = - | 'irrelevant' - | 'notAccurate' - | 'outOfDate' - | 'harmful'; - export type GeneratedAnswerFeedbackOption = 'yes' | 'unknown' | 'no'; -export type GeneratedAnswerFeedbackV2 = { +export type GeneratedAnswerFeedback = { helpful: boolean; documented: GeneratedAnswerFeedbackOption; correctTopic: GeneratedAnswerFeedbackOption; @@ -31,12 +25,6 @@ export type GeneratedAnswerFeedbackV2 = { }; const RGAType = 'RGA'; -export function isGeneratedAnswerFeedbackV2( - feedback: GeneratedAnswerFeedback | GeneratedAnswerFeedbackV2 -): feedback is GeneratedAnswerFeedbackV2 { - return typeof feedback === 'object'; -} - //TODO: KIT-2859 export const logRetryGeneratedAnswer = (): LegacySearchAction => makeAnalyticsAction('analytics/generatedAnswer/retry', (client) => @@ -180,64 +168,7 @@ export const logDislikeGeneratedAnswer = (): CustomAction => }); export const logGeneratedAnswerFeedback = ( - feedback: GeneratedAnswerFeedback | GeneratedAnswerFeedbackV2 -): CustomAction => - makeAnalyticsAction({ - prefix: 'analytics/generatedAnswer/sendFeedback', - __legacy__getBuilder: (client, state) => { - const generativeQuestionAnsweringId = - generativeQuestionAnsweringIdSelector(state); - if (!generativeQuestionAnsweringId) { - return null; - } - return isGeneratedAnswerFeedbackV2(feedback) - ? client.makeGeneratedAnswerFeedbackSubmitV2({ - generativeQuestionAnsweringId, - ...feedback, - }) - : client.makeGeneratedAnswerFeedbackSubmit({ - generativeQuestionAnsweringId, - reason: feedback, - }); - }, - analyticsType: isGeneratedAnswerFeedbackV2(feedback) - ? 'Qna.SubmitRgaFeedback' - : undefined, - analyticsPayloadBuilder: isGeneratedAnswerFeedbackV2(feedback) - ? (state): Qna.SubmitRgaFeedback => { - const {search} = state; - const {response} = search || {}; - const responseId = response?.searchUid || ''; - const { - helpful, - readable, - documented, - details, - hallucinationFree: hallucination_free, - correctTopic: correct_topic, - documentUrl: document_url, - } = feedback; - return { - answer: { - responseId, - }, - feedback: { - helpful, - readable, - documented, - details, - hallucination_free, - correct_topic, - document_url, - }, - }; - } - : undefined, - }); - -//Method deprecated after v3, it will no longer be used, TODO: SFINT-5585 -export const logGeneratedAnswerDetailedFeedback = ( - details: string + feedback: GeneratedAnswerFeedback ): CustomAction => makeAnalyticsAction({ prefix: 'analytics/generatedAnswer/sendFeedback', @@ -247,12 +178,40 @@ export const logGeneratedAnswerDetailedFeedback = ( if (!generativeQuestionAnsweringId) { return null; } - return client.makeGeneratedAnswerFeedbackSubmit({ + return client.makeGeneratedAnswerFeedbackSubmitV2({ generativeQuestionAnsweringId, - reason: 'other', - details, + ...feedback, }); }, + analyticsType: 'Qna.SubmitRgaFeedback', + analyticsPayloadBuilder: (state): Qna.SubmitRgaFeedback => { + const {search} = state; + const {response} = search || {}; + const responseId = response?.searchUid || ''; + const { + helpful, + readable, + documented, + details, + hallucinationFree: hallucination_free, + correctTopic: correct_topic, + documentUrl: document_url, + } = feedback; + return { + answer: { + responseId, + }, + feedback: { + helpful, + readable, + documented, + details, + hallucination_free, + correct_topic, + document_url, + }, + }; + }, }); //TODO: SFINT-5435 @@ -417,7 +376,6 @@ export const generatedAnswerAnalyticsClient = { logGeneratedAnswerHideAnswers, logGeneratedAnswerShowAnswers, logGeneratedAnswerStreamEnd, - logGeneratedAnswerDetailedFeedback, logGeneratedAnswerFeedback, logDislikeGeneratedAnswer, logLikeGeneratedAnswer, diff --git a/packages/headless/src/features/generated-answer/generated-answer-insight-analytics-actions.test.ts b/packages/headless/src/features/generated-answer/generated-answer-insight-analytics-actions.test.ts index 7a1f462057f..560ce5bba59 100644 --- a/packages/headless/src/features/generated-answer/generated-answer-insight-analytics-actions.test.ts +++ b/packages/headless/src/features/generated-answer/generated-answer-insight-analytics-actions.test.ts @@ -8,9 +8,8 @@ import {buildMockInsightState} from '../../test/mock-insight-state'; import {buildMockSearchResponse} from '../../test/mock-search-response'; import {buildMockSearchState} from '../../test/mock-search-state'; import {getConfigurationInitialState} from '../configuration/configuration-state'; -import {GeneratedAnswerFeedbackV2} from './generated-answer-analytics-actions'; +import {GeneratedAnswerFeedback} from './generated-answer-analytics-actions'; import { - logGeneratedAnswerDetailedFeedback, logGeneratedAnswerFeedback, logRetryGeneratedAnswer, logRephraseGeneratedAnswer, @@ -79,8 +78,7 @@ jest.mock('coveo.analytics', () => { }; }); -const exampleFeedback = 'irrelevant'; -const exampleFeedbackV2: GeneratedAnswerFeedbackV2 = { +const exampleFeedback: GeneratedAnswerFeedback = { helpful: true, documented: 'yes', correctTopic: 'no', @@ -89,7 +87,6 @@ const exampleFeedbackV2: GeneratedAnswerFeedbackV2 = { }; const exampleGenerativeQuestionAnsweringId = '123'; const exampleSearchUid = '456'; -const exampleDetails = 'example details'; const exampleCitationId = 'citation_id'; const exampleCitationPermanentid = 'citation_permanentid'; const exampleSubject = 'example subject'; @@ -274,28 +271,8 @@ describe('generated answer insight analytics actions', () => { ); }); - it('should log #logGeneratedAnswerFeedback with V1 payload', async () => { - await logGeneratedAnswerFeedback(exampleFeedback)()( - engine.dispatch, - () => engine.state, - {} as ThunkExtraArguments - ); - - const mockToUse = mockLogGeneratedAnswerFeedbackSubmit; - const expectedMetadata = { - generativeQuestionAnsweringId: exampleGenerativeQuestionAnsweringId, - reason: exampleFeedback, - }; - - expect(mockToUse).toHaveBeenCalledTimes(1); - expect(mockToUse).toHaveBeenCalledWith( - expectedMetadata, - expectedCaseContext - ); - }); - it('should log #logGeneratedAnswerFeedback with V2 payload', async () => { - await logGeneratedAnswerFeedback(exampleFeedbackV2)()( + await logGeneratedAnswerFeedback(exampleFeedback)()( engine.dispatch, () => engine.state, {} as ThunkExtraArguments @@ -304,28 +281,7 @@ describe('generated answer insight analytics actions', () => { const mockToUse = mockLogGeneratedAnswerFeedbackSubmitV2; const expectedMetadata = { generativeQuestionAnsweringId: exampleGenerativeQuestionAnsweringId, - ...exampleFeedbackV2, - }; - - expect(mockToUse).toHaveBeenCalledTimes(1); - expect(mockToUse).toHaveBeenCalledWith( - expectedMetadata, - expectedCaseContext - ); - }); - - it('should log #logGeneratedAnswerDetailedFeedback with the right payload', async () => { - await logGeneratedAnswerDetailedFeedback(exampleDetails)()( - engine.dispatch, - () => engine.state, - {} as ThunkExtraArguments - ); - - const mockToUse = mockLogGeneratedAnswerFeedbackSubmit; - const expectedMetadata = { - generativeQuestionAnsweringId: exampleGenerativeQuestionAnsweringId, - reason: 'other', - details: exampleDetails, + ...exampleFeedback, }; expect(mockToUse).toHaveBeenCalledTimes(1); @@ -512,19 +468,8 @@ describe('generated answer insight analytics actions', () => { expect(emit.mock.calls[0]).toMatchSnapshot(); }); - it('should log #logGeneratedAnswerDetailedFeedback with the right payload', async () => { - await logGeneratedAnswerDetailedFeedback(exampleDetails)()( - engine.dispatch, - () => engine.state, - {} as ThunkExtraArguments - ); - - expect(emit).toHaveBeenCalledTimes(0); - expect(emit.mock.calls[0]).toMatchSnapshot(); - }); - it('should log #logGeneratedAnswerFeedback with the right payload', async () => { - await logGeneratedAnswerFeedback(exampleFeedbackV2)()( + await logGeneratedAnswerFeedback(exampleFeedback)()( engine.dispatch, () => engine.state, {} as ThunkExtraArguments diff --git a/packages/headless/src/features/generated-answer/generated-answer-insight-analytics-actions.ts b/packages/headless/src/features/generated-answer/generated-answer-insight-analytics-actions.ts index d9c06056061..306da9985a6 100644 --- a/packages/headless/src/features/generated-answer/generated-answer-insight-analytics-actions.ts +++ b/packages/headless/src/features/generated-answer/generated-answer-insight-analytics-actions.ts @@ -5,11 +5,7 @@ import { } from '../analytics/analytics-utils'; import {SearchPageEvents} from '../analytics/search-action-cause'; import {getCaseContextAnalyticsMetadata} from '../case-context/case-context-state'; -import { - GeneratedAnswerFeedback, - GeneratedAnswerFeedbackV2, - isGeneratedAnswerFeedbackV2, -} from './generated-answer-analytics-actions'; +import {GeneratedAnswerFeedback} from './generated-answer-analytics-actions'; import { citationSourceSelector, generativeQuestionAnsweringIdSelector, @@ -190,72 +186,7 @@ export const logDislikeGeneratedAnswer = (): InsightAction => }); export const logGeneratedAnswerFeedback = ( - feedback: GeneratedAnswerFeedback | GeneratedAnswerFeedbackV2 -): InsightAction => - makeInsightAnalyticsActionFactory( - SearchPageEvents.generatedAnswerFeedbackSubmit - )({ - prefix: 'analytics/generatedAnswer/sendFeedback', - __legacy__getBuilder: (client, state) => { - const generativeQuestionAnsweringId = - generativeQuestionAnsweringIdSelector(state); - if (!generativeQuestionAnsweringId) { - return null; - } - return isGeneratedAnswerFeedbackV2(feedback) - ? client.logGeneratedAnswerFeedbackSubmitV2( - { - generativeQuestionAnsweringId, - ...feedback, - }, - getCaseContextAnalyticsMetadata(state.insightCaseContext) - ) - : client.logGeneratedAnswerFeedbackSubmit( - { - generativeQuestionAnsweringId, - reason: feedback, - }, - getCaseContextAnalyticsMetadata(state.insightCaseContext) - ); - }, - analyticsType: isGeneratedAnswerFeedbackV2(feedback) - ? 'Qna.SubmitRgaFeedback' - : undefined, - analyticsPayloadBuilder: isGeneratedAnswerFeedbackV2(feedback) - ? (state): Qna.SubmitRgaFeedback => { - const {search} = state; - const {response} = search || {}; - const responseId = response?.searchUid || ''; - const { - helpful, - readable, - documented, - details, - hallucinationFree: hallucination_free, - correctTopic: correct_topic, - documentUrl: document_url, - } = feedback; - return { - answer: { - responseId, - }, - feedback: { - helpful, - readable, - documented, - details, - hallucination_free, - correct_topic, - document_url, - }, - }; - } - : undefined, - }); - -//Method deprecated after v3, EP event no longer available, TODO: SFINT-5585 -export const logGeneratedAnswerDetailedFeedback = ( - details: string + feedback: GeneratedAnswerFeedback ): InsightAction => makeInsightAnalyticsActionFactory( SearchPageEvents.generatedAnswerFeedbackSubmit @@ -267,15 +198,43 @@ export const logGeneratedAnswerDetailedFeedback = ( if (!generativeQuestionAnsweringId) { return null; } - return client.logGeneratedAnswerFeedbackSubmit( + return client.logGeneratedAnswerFeedbackSubmitV2( { generativeQuestionAnsweringId, - reason: 'other', - details, + ...feedback, }, getCaseContextAnalyticsMetadata(state.insightCaseContext) ); }, + analyticsType: 'Qna.SubmitRgaFeedback', + analyticsPayloadBuilder: (state): Qna.SubmitRgaFeedback => { + const {search} = state; + const {response} = search || {}; + const responseId = response?.searchUid || ''; + const { + helpful, + readable, + documented, + details, + hallucinationFree: hallucination_free, + correctTopic: correct_topic, + documentUrl: document_url, + } = feedback; + return { + answer: { + responseId, + }, + feedback: { + helpful, + readable, + documented, + details, + hallucination_free, + correct_topic, + document_url, + }, + }; + }, }); //TODO: SFINT-5435 @@ -451,7 +410,6 @@ export const generatedAnswerInsightAnalyticsClient = { logGeneratedAnswerHideAnswers, logGeneratedAnswerShowAnswers, logGeneratedAnswerStreamEnd, - logGeneratedAnswerDetailedFeedback, logGeneratedAnswerFeedback, logDislikeGeneratedAnswer, logLikeGeneratedAnswer, diff --git a/packages/headless/src/index.ts b/packages/headless/src/index.ts index ac02a684885..3eee4aafa93 100644 --- a/packages/headless/src/index.ts +++ b/packages/headless/src/index.ts @@ -639,6 +639,5 @@ export * from './utils/query-expression/query-expression'; export type { GeneratedAnswerFeedback, - GeneratedAnswerFeedbackV2, GeneratedAnswerFeedbackOption, } from './features/generated-answer/generated-answer-analytics-actions';