Skip to content

Make chat elicitation request part accessible #257491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 23, 2025
Prev Previous commit
Next Next commit
add to elicitationHint
  • Loading branch information
meganrogge committed Jul 23, 2025
commit a81b17a75ab819267701b93afa25ce0cefb0444f
4 changes: 2 additions & 2 deletions src/vs/workbench/contrib/chat/browser/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { IChatAgentCommand, IChatAgentData } from '../common/chatAgents.js';
import { IChatResponseModel } from '../common/chatModel.js';
import { IParsedChatRequest } from '../common/chatParserTypes.js';
import { CHAT_PROVIDER_ID } from '../common/chatParticipantContribTypes.js';
import { IChatSendRequestOptions } from '../common/chatService.js';
import { IChatElicitationRequest, IChatSendRequestOptions } from '../common/chatService.js';
import { IChatRequestViewModel, IChatResponseViewModel, IChatViewModel } from '../common/chatViewModel.js';
import { ChatAgentLocation, ChatModeKind } from '../common/constants.js';
import { ChatAttachmentModel } from './chatAttachmentModel.js';
Expand Down Expand Up @@ -92,7 +92,7 @@ export interface IChatAccessibilityService {
readonly _serviceBrand: undefined;
acceptRequest(): number;
acceptResponse(response: IChatResponseViewModel | string | undefined, requestId: number, isVoiceInput?: boolean): void;
acceptElicitation(message: string): void;
acceptElicitation(message: IChatElicitationRequest): void;
}

export interface IChatCodeBlockInfo {
Expand Down
30 changes: 13 additions & 17 deletions src/vs/workbench/contrib/chat/browser/chatAccessibilityProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,33 +128,29 @@ export class ChatAccessibilityProvider implements IListAccessibilityProvider<Cha
break;
}

const elicitationCount = element.response.value.filter(v => v.kind === 'elicitation').length ?? 0;
let elicitationCountHint = '';
switch (elicitationCount) {
case 0:
break;
case 1:
elicitationCountHint = localize('singleElicitationHint', "1 user input request ");
break;
default:
elicitationCountHint = localize('multiElicitationHint', "{0} user input requests ", elicitationCount);
break;
const elicitationCount = element.response.value.filter(v => v.kind === 'elicitation');
let elicitationHint = '';
for (const elicitation of elicitationCount) {
const title = typeof elicitation.title === 'string' ? elicitation.title : elicitation.title.value;
const message = typeof elicitation.message === 'string' ? elicitation.message : elicitation.message.value;
elicitationHint += title + ' ' + message;
}

const codeBlockCount = marked.lexer(element.response.toString()).filter(token => token.type === 'code')?.length ?? 0;
switch (codeBlockCount) {
case 0:
label = accessibleViewHint
? localize('noCodeBlocksHint', "{0}{1}{2}{3}{4} {5}", toolInvocationHint, fileTreeCountHint, elicitationCountHint, tableCountHint, element.response.toString(), accessibleViewHint)
label = accessibleViewHint
? localize('noCodeBlocksHint', "{0}{1}{2}{3}{4} {5}", toolInvocationHint, fileTreeCountHint, elicitationCountHint, tableCountHint, element.response.toString(), accessibleViewHint)
: localize('noCodeBlocks', "{0}{1}{2} {3}", fileTreeCountHint, elicitationCountHint, tableCountHint, element.response.toString());
break;
case 1:
label = accessibleViewHint
? localize('singleCodeBlockHint', "{0}{1}{2}1 code block: {3} {4}{5}", toolInvocationHint, fileTreeCountHint, elicitationCountHint, tableCountHint, element.response.toString(), accessibleViewHint)
label = accessibleViewHint
? localize('singleCodeBlockHint', "{0}{1}{2}1 code block: {3} {4}{5}", toolInvocationHint, fileTreeCountHint, elicitationCountHint, tableCountHint, element.response.toString(), accessibleViewHint)
: localize('singleCodeBlock', "{0}{1}1 code block: {2} {3}", fileTreeCountHint, elicitationCountHint, tableCountHint, element.response.toString());
break;
default:
label = accessibleViewHint
? localize('multiCodeBlockHint', "{0}{1}{2}{3} code blocks: {4}{5} {6}", toolInvocationHint, fileTreeCountHint, elicitationCountHint, tableCountHint, codeBlockCount, element.response.toString(), accessibleViewHint)
label = accessibleViewHint
? localize('multiCodeBlockHint', "{0}{1}{2}{3} code blocks: {4}{5} {6}", toolInvocationHint, fileTreeCountHint, elicitationCountHint, tableCountHint, codeBlockCount, element.response.toString(), accessibleViewHint)
: localize('multiCodeBlock', "{0}{1}{2} code blocks: {3} {4}", fileTreeCountHint, elicitationCountHint, codeBlockCount, tableCountHint, element.response.toString());
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { renderAsPlaintext } from '../../../../base/browser/markdownRenderer.js'
import { MarkdownString } from '../../../../base/common/htmlContent.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
import { AccessibilityVoiceSettingId } from '../../accessibility/browser/accessibilityConfiguration.js';
import { IChatElicitationRequest } from '../common/chatService.js';

const CHAT_RESPONSE_PENDING_ALLOWANCE_MS = 4000;
export class ChatAccessibilityService extends Disposable implements IChatAccessibilityService {
Expand Down Expand Up @@ -51,8 +52,10 @@ export class ChatAccessibilityService extends Disposable implements IChatAccessi
status(plainTextResponse + errorDetails);
}
}
acceptElicitation(message: string): void {
alert('User input required: ' + message);
acceptElicitation(elicitation: IChatElicitationRequest): void {
const title = typeof elicitation.title === 'string' ? elicitation.title : elicitation.title.value;
const message = typeof elicitation.message === 'string' ? elicitation.message : elicitation.message.value;
alert(title + ' ' + message);
this._accessibilitySignalService.playSignal(AccessibilitySignal.chatUserActionRequired, { allowManyInParallel: true });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export class ChatElicitationContentPart extends Disposable implements IChatConte
}));


this.chatAccessibilityService.acceptElicitation(typeof elicitation.message === 'string' ? elicitation.message : elicitation.message.value);
this.chatAccessibilityService.acceptElicitation(elicitation);
this.domNode = confirmationWidget.domNode;
this.domNode.tabIndex = 0;
this.domNode.ariaLabel = typeof messageToRender === 'string' ? messageToRender : messageToRender.value || '';
Expand Down
Loading