Skip to content

Commit

Permalink
Issue: microsoft#214481 Add Option to Ignore Code Blocks in Text-to-S…
Browse files Browse the repository at this point in the history
…peech (microsoft#235697)

* Add Option to Ignore Code Blocks in Text-to-Speech

* Add Option to Ignore Code Blocks in Text-to-Speech

* clean up

---------

Co-authored-by: Benjamin Pasero <[email protected]>
Co-authored-by: Benjamin Pasero <[email protected]>
  • Loading branch information
3 people authored Dec 12, 2024
1 parent 9fbfe5d commit 6a5c8cf
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,12 @@ export class DynamicSpeechAccessibilityConfiguration extends Disposable implemen
'minimum': 0,
'tags': ['accessibility']
},
[AccessibilityVoiceSettingId.IgnoreCodeBlocks]: {
'markdownDescription': localize('voice.ignoreCodeBlocks', "Whether to ignore code snippets in text-to-speech synthesis."),
'type': 'boolean',
'default': false,
'tags': ['accessibility']
},
[AccessibilityVoiceSettingId.SpeechLanguage]: {
'markdownDescription': localize('voice.speechLanguage', "The language that text-to-speech and speech-to-text should use. Select `auto` to use the configured display language if possible. Note that not all display languages maybe supported by speech recognition and synthesizers."),
'type': 'string',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,11 @@ class ChatSynthesizerSessionController {
}
}

interface IChatSyntheSizerContext {
readonly ignoreCodeBlocks: boolean;
insideCodeBlock: boolean;
}

class ChatSynthesizerSessions {

private static instance: ChatSynthesizerSessions | undefined = undefined;
Expand All @@ -722,6 +727,7 @@ class ChatSynthesizerSessions {

constructor(
@ISpeechService private readonly speechService: ISpeechService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IInstantiationService private readonly instantiationService: IInstantiationService
) { }

Expand Down Expand Up @@ -768,11 +774,16 @@ class ChatSynthesizerSessions {
}

private async *nextChatResponseChunk(response: IChatResponseModel, token: CancellationToken): AsyncIterable<string> {
const context: IChatSyntheSizerContext = {
ignoreCodeBlocks: this.configurationService.getValue<boolean>(AccessibilityVoiceSettingId.IgnoreCodeBlocks),
insideCodeBlock: false
};

let totalOffset = 0;
let complete = false;
do {
const responseLength = response.response.toString().length;
const { chunk, offset } = this.parseNextChatResponseChunk(response, totalOffset);
const { chunk, offset } = this.parseNextChatResponseChunk(response, totalOffset, context);
totalOffset = offset;
complete = response.isComplete;

Expand All @@ -790,7 +801,7 @@ class ChatSynthesizerSessions {
} while (!token.isCancellationRequested && !complete);
}

private parseNextChatResponseChunk(response: IChatResponseModel, offset: number): { readonly chunk: string | undefined; readonly offset: number } {
private parseNextChatResponseChunk(response: IChatResponseModel, offset: number, context: IChatSyntheSizerContext): { readonly chunk: string | undefined; readonly offset: number } {
let chunk: string | undefined = undefined;

const text = response.response.toString();
Expand All @@ -804,12 +815,28 @@ class ChatSynthesizerSessions {
offset = res.offset;
}

if (chunk && context.ignoreCodeBlocks) {
chunk = this.filterCodeBlocks(chunk, context);
}

return {
chunk: chunk ? renderStringAsPlaintext({ value: chunk }) : chunk, // convert markdown to plain text
offset
};
}

private filterCodeBlocks(chunk: string, context: IChatSyntheSizerContext): string {
return chunk.split('\n')
.filter(line => {
if (line.trimStart().startsWith('```')) {
context.insideCodeBlock = !context.insideCodeBlock;
return false;
}
return !context.insideCodeBlock;
})
.join('\n');
}

stop(): void {
this.activeSession?.dispose(true);
this.activeSession = undefined;
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/contrib/speech/common/speechService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export const enum AccessibilityVoiceSettingId {
SpeechTimeout = 'accessibility.voice.speechTimeout',
AutoSynthesize = 'accessibility.voice.autoSynthesize',
SpeechLanguage = 'accessibility.voice.speechLanguage',
IgnoreCodeBlocks = 'accessibility.voice.ignoreCodeBlocks'
}

export const SPEECH_LANGUAGE_CONFIG = AccessibilityVoiceSettingId.SpeechLanguage;
Expand Down

0 comments on commit 6a5c8cf

Please sign in to comment.