0

recorder: Prefill GenAI feedback

Have different hashtags for summary and title suggestion, and include
the model input/output.

Bug: b:396573662
Test: manually - click thumb down button and see feedback dialog
Change-Id: I531adcf21378c7b5f21519b1daa04f0133f05b30
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6298267
Reviewed-by: Pi-Hsun Shih <pihsun@chromium.org>
Commit-Queue: Jennifer Ling <hsuanling@google.com>
Cr-Commit-Position: refs/heads/main@{#1425030}
This commit is contained in:
hsuanling
2025-02-26 02:00:14 -08:00
committed by Chromium LUCI CQ
parent 89b83d2f1f
commit ea157aa185
11 changed files with 86 additions and 12 deletions

@ -45,6 +45,13 @@ const webui::LocalizedString kLocalizedStrings[] = {
{"genAiErrorTitleSuggestionTrustAndSafetyLabel",
IDS_RECORDER_GEN_AI_ERROR_TITLE_SUGGESTION_TRUST_AND_SAFETY_LABEL},
{"genAiExperimentBadge", IDS_RECORDER_GEN_AI_EXPERIMENT_BADGE},
{"genAiFeedbackModelInputField",
IDS_RECORDER_GEN_AI_FEEDBACK_MODEL_INPUT_FIELD},
{"genAiFeedbackPrompt", IDS_RECORDER_GEN_AI_FEEDBACK_PROMPT},
{"genAiFeedbackSummaryOutputField",
IDS_RECORDER_GEN_AI_FEEDBACK_SUMMARY_OUTPUT_FIELD},
{"genAiFeedbackTitleSuggestionOutputField",
IDS_RECORDER_GEN_AI_FEEDBACK_TITLE_SUGGESTION_OUTPUT_FIELD},
{"genAiLearnMoreLink", IDS_RECORDER_GEN_AI_LEARN_MORE_LINK},
{"genAiLearnMoreLinkTooltip", IDS_RECORDER_GEN_AI_LEARN_MORE_LINK_TOOLTIP},
{"genaiNegativeFeedbackButtonTooltip",

@ -61,6 +61,10 @@ export class GenaiFeedbackButtons extends ReactiveLitElement {
resultType: GenaiResultType|null = null;
result: string|null = null;
transcription: string|null = null;
private sendFeedbackEvent(rating: UserRating): void {
if (this.resultType === null) {
return;
@ -79,6 +83,40 @@ export class GenaiFeedbackButtons extends ReactiveLitElement {
}
}
/**
* Creates template consisting four parts: hashtags, feedback prompt, GenAI
* results, and transcript used.
*/
private createFeedbackTemplate(): string {
const templateParts: string[] = [];
let hashTag = '#RecorderApp';
switch (this.resultType) {
case GenaiResultType.TITLE_SUGGESTION:
hashTag += ' #NameCreation';
break;
case GenaiResultType.SUMMARY:
hashTag += ' #Summary';
break;
default:
break;
}
templateParts.push(hashTag);
templateParts.push(i18n.genAiFeedbackPrompt);
if (this.result !== null) {
const outputField = this.resultType === GenaiResultType.SUMMARY ?
i18n.genAiFeedbackSummaryOutputField :
i18n.genAiFeedbackTitleSuggestionOutputField;
templateParts.push(`${outputField}\n${this.result}`);
}
if (this.transcription !== null) {
templateParts.push(
`${i18n.genAiFeedbackModelInputField}\n${this.transcription}`,
);
}
// Separates each part with an empty line.
return templateParts.join('\n\n');
}
private onThumbUpClick() {
if (this.userRating.value === UserRating.THUMB_UP) {
this.userRating.value = null;
@ -94,10 +132,7 @@ export class GenaiFeedbackButtons extends ReactiveLitElement {
} else {
this.userRating.value = UserRating.THUMB_DOWN;
this.sendFeedbackEvent(UserRating.THUMB_DOWN);
// TODO: b/344789836 - Determine what should be the default description
// for the feedback report (we likely want the model input & output), and
// also put it into recorder_strings.grdp for i18n.
this.platformHandler.showAiFeedbackDialog('#RecorderApp');
this.platformHandler.showAiFeedbackDialog(this.createFeedbackTemplate());
}
}

@ -130,12 +130,15 @@ export class RecordingTitleSuggestion extends ReactiveLitElement {
static override properties: PropertyDeclarations = {
suggestedTitles: {attribute: false},
transcription: {attribute: false},
wordCount: {attribute: false},
};
suggestedTitles: ScopedAsyncComputed<ModelResponse<string[]>|null>|null =
null;
transcription: string|null = null;
wordCount = 0;
private readonly closeButtonRef = createRef<CraIconButton>();
@ -201,7 +204,7 @@ export class RecordingTitleSuggestion extends ReactiveLitElement {
></cros-chip>`;
}
private renderSuggestionFooter() {
private renderSuggestionFooter(result: string) {
return html`
<div id="footer">
${i18n.genAiDisclaimerText}
@ -213,8 +216,11 @@ export class RecordingTitleSuggestion extends ReactiveLitElement {
${i18n.genAiLearnMoreLink}
</a>
</div>
<genai-feedback-buttons .resultType=${GenaiResultType.TITLE_SUGGESTION}>
</genai-feedback-buttons>
<genai-feedback-buttons
.resultType=${GenaiResultType.TITLE_SUGGESTION}
.result=${result}
.transcription=${this.transcription}
></genai-feedback-buttons>
`;
}
@ -250,11 +256,13 @@ export class RecordingTitleSuggestion extends ReactiveLitElement {
suggestedTitles.result,
(s, index) => this.renderSuggestion(s, index),
);
const concatenatedTitles =
suggestedTitles.result.map((title) => '- ' + title).join('\n');
return html`<spoken-message role="status" aria-live="polite">
${i18n.titleSuggestionFinishedStatusMessage}
</spoken-message>
<div id="suggestions">${suggestions}</div>
${this.renderSuggestionFooter()}`;
${this.renderSuggestionFooter(concatenatedTitles)}`;
}
default:
assertExhaustive(suggestedTitles);

@ -268,6 +268,7 @@ export class RecordingTitle extends ReactiveLitElement {
@change=${this.onSuggestTitle}
.suggestedTitles=${this.suggestedTitles}
.wordCount=${this.transcription.value?.getWordCount() ?? 0}
.transcription=${this.transcription.value?.toPlainText() ?? ''}
${ref(this.recordingTitleSuggestion)}
></recording-title-suggestion>`;
}

@ -239,7 +239,7 @@ export class SummarizationView extends ReactiveLitElement {
});
}
private renderSummaryFooter() {
private renderSummaryFooter(result: string) {
return html`
<div id="footer">
${i18n.genAiDisclaimerText}
@ -251,8 +251,11 @@ export class SummarizationView extends ReactiveLitElement {
${i18n.genAiLearnMoreLink}
</a>
</div>
<genai-feedback-buttons .resultType=${GenaiResultType.SUMMARY}>
</genai-feedback-buttons>
<genai-feedback-buttons
.resultType=${GenaiResultType.SUMMARY}
.result=${result}
.transcription=${this.transcription?.toPlainText() ?? ''}
></genai-feedback-buttons>
`;
}
@ -292,7 +295,7 @@ export class SummarizationView extends ReactiveLitElement {
<ul id="summary" ${ref(this.summaryContainer)}>
${this.renderSummaryResult(summary.result)}
</ul>
${this.renderSummaryFooter()}`;
${this.renderSummaryFooter(summary.result)}`;
default:
assertExhaustive(summary);
}

@ -42,6 +42,10 @@ const noArgStringNames = [
'genAiErrorTitleSuggestionTranscriptTooShortLabel',
'genAiErrorTitleSuggestionTrustAndSafetyLabel',
'genAiExperimentBadge',
'genAiFeedbackModelInputField',
'genAiFeedbackPrompt',
'genAiFeedbackSummaryOutputField',
'genAiFeedbackTitleSuggestionOutputField',
'genAiLearnMoreLink',
'genAiLearnMoreLinkTooltip',
'genaiNegativeFeedbackButtonTooltip',

@ -77,6 +77,18 @@
<message desc="Badge for experimental state of generative AI features." name="IDS_RECORDER_GEN_AI_EXPERIMENT_BADGE">
Experiment
</message>
<message desc="Field for model input in the GenAI feedback template." name="IDS_RECORDER_GEN_AI_FEEDBACK_MODEL_INPUT_FIELD">
Transcript:
</message>
<message desc="Prompt for user feedback in the GenAI feedback template." name="IDS_RECORDER_GEN_AI_FEEDBACK_PROMPT">
Share your feedback or describe your issue
</message>
<message desc="Field for generated summary in the GenAI feedback template." name="IDS_RECORDER_GEN_AI_FEEDBACK_SUMMARY_OUTPUT_FIELD">
Generated summary:
</message>
<message desc="Field for generated titles in the GenAI feedback template." name="IDS_RECORDER_GEN_AI_FEEDBACK_TITLE_SUGGESTION_OUTPUT_FIELD">
Generated names:
</message>
<message desc="Link to more information about generative AI disclaimer." name="IDS_RECORDER_GEN_AI_LEARN_MORE_LINK">
Learn more
</message>

@ -0,0 +1 @@
16527533e41dfb1ea0b10938952db50e306a2eb2

@ -0,0 +1 @@
1aab9afdf8a6f4eabb6d351b47feb6615b87f063

@ -0,0 +1 @@
1aab9afdf8a6f4eabb6d351b47feb6615b87f063

@ -0,0 +1 @@
c1e707fde69bef5006cbc499faf94fa62cb86844