-
Notifications
You must be signed in to change notification settings - Fork 59.3k
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
feat: add tts & stt #5329
feat: add tts & stt #5329
Conversation
@DDMeaqua is attempting to deploy a commit to the NextChat Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThe changes introduce extensive enhancements to the application, focusing on adding speech synthesis and transcription functionalities. New constants, interfaces, and methods are implemented across various files, enabling structured handling of speech options and configurations. Additionally, components for managing text-to-speech and speech-to-text settings are introduced, enhancing the overall capabilities of the application. Changes
Possibly related PRs
Suggested reviewers
Poem
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 15
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files ignored due to path filters (4)
app/icons/speak-stop.svg
is excluded by!**/*.svg
app/icons/speak.svg
is excluded by!**/*.svg
app/icons/voice-white.svg
is excluded by!**/*.svg
yarn.lock
is excluded by!**/yarn.lock
,!**/*.lock
Files selected for processing (26)
- app/client/api.ts (3 hunks)
- app/client/platforms/alibaba.ts (1 hunks)
- app/client/platforms/anthropic.ts (1 hunks)
- app/client/platforms/baidu.ts (1 hunks)
- app/client/platforms/bytedance.ts (1 hunks)
- app/client/platforms/google.ts (1 hunks)
- app/client/platforms/iflytek.ts (1 hunks)
- app/client/platforms/moonshot.ts (1 hunks)
- app/client/platforms/openai.ts (3 hunks)
- app/client/platforms/tencent.ts (1 hunks)
- app/components/chat.tsx (11 hunks)
- app/components/settings.tsx (2 hunks)
- app/components/stt-config.tsx (1 hunks)
- app/components/stt.module.scss (1 hunks)
- app/components/tts-config.tsx (1 hunks)
- app/components/tts.module.scss (1 hunks)
- app/constant.ts (2 hunks)
- app/locales/cn.ts (3 hunks)
- app/locales/en.ts (1 hunks)
- app/locales/index.ts (1 hunks)
- app/store/access.ts (2 hunks)
- app/store/config.ts (3 hunks)
- app/utils/audio.ts (1 hunks)
- app/utils/ms_edge_tts.ts (1 hunks)
- app/utils/speech.ts (1 hunks)
- package.json (2 hunks)
Additional context used
Biome
app/utils/audio.ts
[error] 3-3: void is confusing inside a union type.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 16-16: void is confusing inside a union type.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
app/components/stt-config.tsx
[error] 23-23: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 35-37: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
app/components/tts-config.tsx
[error] 28-28: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 53-55: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 74-76: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 96-98: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 121-123: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
Gitleaks
app/utils/ms_edge_tts.ts
121-121: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
Additional comments not posted (71)
app/utils/audio.ts (2)
11-14
: LGTM!The function is correctly implemented.
The code changes are approved.
32-41
: LGTM!The function is correctly implemented.
The code changes are approved.
package.json (1)
33-33
: LGTM!The new dependency is correctly added.
The code changes are approved.
app/components/stt.module.scss (4)
2-5
: LGTM!The styles for the
.plugin-page
class are correctly implemented.The code changes are approved.
7-9
: LGTM!The styles for the
.plugin-page-body
class are correctly implemented.The code changes are approved.
11-17
: LGTM!The styles for the
.plugin-filter
class are correctly implemented.The code changes are approved.
44-116
: LGTM!The styles for the
.plugin-item
class are correctly implemented.The code changes are approved.
app/components/tts.module.scss (4)
2-5
: LGTM!The styles for the
.plugin-page
class are correctly implemented.The code changes are approved.
7-9
: LGTM!The styles for the
.plugin-page-body
class are correctly implemented.The code changes are approved.
11-17
: LGTM!The styles for the
.plugin-filter
class are correctly implemented.The code changes are approved.
44-116
: LGTM!The styles for the
.plugin-item
class are correctly implemented.The code changes are approved.
app/locales/index.ts (2)
141-162
: LGTM!The constants
DEFAULT_STT_LANG
andSTT_LANG_MAP
are correctly defined and enhance the application's localization capabilities.The code changes are approved.
164-170
: LGTM!The
getSTTLang
function is correctly implemented with robust error handling.The code changes are approved.
app/utils/speech.ts (1)
7-17
: LGTM!The
SpeechApi
abstract class is well-structured and provides a clear interface for transcription APIs.The code changes are approved.
app/store/config.ts (9)
22-22
: LGTM!The type definition for
TTSModelType
is correct and improves type safety.The code changes are approved.
23-23
: LGTM!The type definition for
TTSVoiceType
is correct and improves type safety.The code changes are approved.
24-24
: LGTM!The type definition for
TTSEngineType
is correct and improves type safety.The code changes are approved.
26-26
: LGTM!The type definition for
STTEngineType
is correct and improves type safety.The code changes are approved.
100-100
: LGTM!The type definition for
TTSConfig
is correct and improves type safety.The code changes are approved.
101-101
: LGTM!The type definition for
STTConfig
is correct and improves type safety.The code changes are approved.
83-94
: LGTM!The updates to
DEFAULT_CONFIG
are correct and enhance the application's capabilities.The code changes are approved.
116-129
: LGTM!The
TTSConfigValidator
is well-structured and ensures correct configurations.The code changes are approved.
131-135
: LGTM!The
STTConfigValidator
is well-structured and ensures correct configurations.The code changes are approved.
app/store/access.ts (2)
123-125
: LGTM!The addition of the
edgeTTSVoiceName
property toDEFAULT_ACCESS_STATE
is correct and aligns with the new TTS functionality.The code changes are approved.
138-142
: LGTM! But verify thefetch
method implementation.The
edgeVoiceName
method is correctly implemented. However, ensure that thefetch
method is correctly defined and does not introduce any side effects.The code changes are approved.
Run the following script to verify the
fetch
method implementation:Verification successful
The
fetch
method is correctly implemented without side effects.The
fetch
method inapp/store/access.ts
manages its state usingfetchState
and logs errors appropriately. It does not introduce any side effects that would impact theedgeVoiceName
method. The implementation is sound and aligns with the intended functionality.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the `fetch` method implementation. # Test: Search for the `fetch` method. Expect: Correct implementation without side effects. rg --type python -A 5 $'fetch()'Length of output: 64
Script:
#!/bin/bash # Description: Verify the `fetch` method implementation in TypeScript files. # Test: Search for the `fetch` method in TypeScript files. Expect: Correct implementation without side effects. rg --type ts -A 5 'fetch()'Length of output: 46404
app/client/platforms/bytedance.ts (1)
80-85
: LGTM! But implement the methods.The
speech
andtranscription
methods are correctly added as placeholders. However, remember to implement these methods in the future.The code changes are approved.
app/client/platforms/iflytek.ts (1)
56-61
: LGTM! But implement the methods.The
speech
andtranscription
methods are correctly added as placeholders. However, remember to implement these methods in the future.The code changes are approved.
app/client/platforms/alibaba.ts (2)
86-88
: LGTM!The
speech
method is correctly added as a placeholder for future implementation.The code changes are approved.
89-91
: LGTM!The
transcription
method is correctly added as a placeholder for future implementation.The code changes are approved.
app/client/platforms/moonshot.ts (2)
69-71
: LGTM!The
speech
method is correctly added as a placeholder for future implementation.The code changes are approved.
72-74
: LGTM!The
transcription
method is correctly added as a placeholder for future implementation.The code changes are approved.
app/client/platforms/tencent.ts (2)
92-94
: LGTM!The
speech
method is correctly added as a placeholder for future implementation.The code changes are approved.
95-97
: LGTM!The
transcription
method is correctly added as a placeholder for future implementation.The code changes are approved.
app/client/platforms/baidu.ts (2)
78-79
: LGTM!The
speech
method is correctly added as a placeholder for future implementation.The code changes are approved.
81-82
: LGTM!The
transcription
method is correctly added as a placeholder for future implementation.The code changes are approved.
app/client/api.ts (5)
23-23
: LGTM!The
TTSModels
constant is correctly defined and provides identifiers for text-to-speech models.The code changes are approved.
52-59
: LGTM!The
SpeechOptions
interface is correctly defined and provides structured configurations for handling speech synthesis requests.The code changes are approved.
61-69
: LGTM!The
TranscriptionOptions
interface is correctly defined and provides structured configurations for handling audio transcription requests.The code changes are approved.
103-103
: LGTM!The
speech
method is correctly added as an abstract method to theLLMApi
class.The code changes are approved.
104-104
: LGTM!The
transcription
method is correctly added as an abstract method to theLLMApi
class.The code changes are approved.
app/client/platforms/google.ts (2)
59-60
: LGTM!The
speech
method is correctly added as a placeholder for future implementation.The code changes are approved.
62-63
: LGTM!The
transcription
method is correctly added as a placeholder for future implementation.The code changes are approved.
app/client/platforms/anthropic.ts (2)
76-78
: LGTM!The
speech
method is correctly defined as a placeholder for future implementation.The code changes are approved.
79-81
: LGTM!The
transcription
method is correctly defined as a placeholder for future implementation.The code changes are approved.
app/constant.ts (2)
156-157
: LGTM!The new paths
SpeechPath
andTranscriptionPath
are correctly added toOpenaiPath
.The code changes are approved.
261-277
: LGTM!The new constants related to TTS and STT functionalities are correctly defined and consistent with existing constants.
The code changes are approved.
app/locales/cn.ts (2)
46-47
: LGTM!The new keys
Speech
andStopSpeech
are correctly added to theActions
section.The code changes are approved.
488-517
: LGTM!The new sections
TTS
andSTT
with multiple sub-keys are correctly defined and consistent with existing sections.The code changes are approved.
app/client/platforms/openai.ts (3)
82-82
: LGTM!The function is correctly implemented and the new parameter is used appropriately.
The code changes are approved.
183-222
: Improve error handling.The function is correctly implemented, but the error handling can be improved by providing more context in the error message.
Apply this diff to improve error handling:
- console.log("[Request] failed to make a audio transcriptions request", e); + console.error("[Request] failed to make an audio transcription request", e);Likely invalid or redundant comment.
145-181
: Improve error handling.The function is correctly implemented, but the error handling can be improved by providing more context in the error message.
Apply this diff to improve error handling:
- console.log("[Request] failed to make a speech request", e); + console.error("[Request] failed to make a speech request", e);Likely invalid or redundant comment.
app/utils/ms_edge_tts.ts (9)
11-19
: LGTM!The enum is correctly implemented.
The code changes are approved.
24-31
: LGTM!The enum is correctly implemented.
The code changes are approved.
36-43
: LGTM!The enum is correctly implemented.
The code changes are approved.
48-86
: LGTM!The enum is correctly implemented.
The code changes are approved.
88-96
: LGTM!The type is correctly implemented.
The code changes are approved.
98-117
: LGTM!The class is correctly implemented.
The code changes are approved.
150-159
: LGTM!The function is correctly implemented.
The code changes are approved.
161-224
: LGTM!The function is correctly implemented.
The code changes are approved.
226-233
: LGTM!The function is correctly implemented.
The code changes are approved.
app/locales/en.ts (1)
48-49
: LGTM!The entries for
Speech
andStopSpeech
are correctly added.The code changes are approved.
app/components/settings.tsx (2)
83-84
: LGTM!The import statements for
TTSConfigList
andSTTConfigList
are correctly added.The code changes are approved.
1651-1672
: LGTM!The integration of
TTSConfigList
andSTTConfigList
within theSettings
function is correctly implemented. TheupdateConfig
function is appropriately used to update the respective configurations.The code changes are approved.
app/components/chat.tsx (8)
13-13
: LGTM!The import statement for
VoiceWhiteIcon
is correct.The code changes are approved.
19-20
: LGTM!The import statements for
SpeakIcon
andSpeakStopIcon
are correct.The code changes are approved.
80-80
: LGTM!The import statement for
Locale
,getLang
, andgetSTTLang
is correct.The code changes are approved.
97-99
: LGTM!The import statement for
DEFAULT_STT_ENGINE
,DEFAULT_TTS_ENGINE
, andFIREFOX_DEFAULT_STT_ENGINE
is correct.The code changes are approved.
117-124
: LGTM!The import statements for
ClientApi
,createTTSPlayer
,OpenAITranscriptionApi
,SpeechApi
,WebTranscriptionApi
,MsEdgeTTS
, andOUTPUT_FORMAT
are correct.The code changes are approved.
126-126
: LGTM!The constant
ttsPlayer
is correctly initialized.The code changes are approved.
456-456
: LGTM!The new prop
setUserInput
is correctly added.The code changes are approved.
548-584
: Verify the dependency array inuseEffect
.The state variables and functions are correctly implemented. However, the dependency array in the
useEffect
hook is empty. This might cause the effect to not re-run whenconfig.sttConfig.engine
changes.Consider adding
config.sttConfig.engine
to the dependency array:useEffect(() => { if (isFirefox()) config.sttConfig.engine = FIREFOX_DEFAULT_STT_ENGINE; setSpeechApi( config.sttConfig.engine === DEFAULT_STT_ENGINE ? new WebTranscriptionApi((transcription) => onRecognitionEnd(transcription), ) : new OpenAITranscriptionApi((transcription) => onRecognitionEnd(transcription), ), ); - }, []); + }, [config.sttConfig.engine]);
const buffer = await audioContext!.decodeAudioData(audioBuffer); | ||
audioBufferSourceNode = audioContext!.createBufferSource(); | ||
audioBufferSourceNode.buffer = buffer; | ||
audioBufferSourceNode.connect(audioContext!.destination); | ||
audioContext!.resume().then(() => { | ||
audioBufferSourceNode!.start(); | ||
}); | ||
audioBufferSourceNode.onended = onended; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add null checks for audioContext
and audioBufferSourceNode
.
Ensure that audioContext
and audioBufferSourceNode
are not null before using them to avoid potential runtime errors.
Apply this diff to fix the issue:
- const buffer = await audioContext!.decodeAudioData(audioBuffer);
- audioBufferSourceNode = audioContext!.createBufferSource();
+ if (!audioContext) throw new Error('AudioContext is not initialized');
+ const buffer = await audioContext.decodeAudioData(audioBuffer);
+ audioBufferSourceNode = audioContext.createBufferSource();
Committable suggestion was skipped due to low confidence.
audioContext!.resume().then(() => { | ||
audioBufferSourceNode!.start(); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for Web Audio API operations.
Add error handling for audioContext.resume()
and audioBufferSourceNode.start()
to handle potential errors gracefully.
Apply this diff to fix the issue:
- audioContext!.resume().then(() => {
- audioBufferSourceNode!.start();
- });
+ try {
+ await audioContext.resume();
+ audioBufferSourceNode.start();
+ } catch (error) {
+ console.error('Error during audio playback:', error);
+ }
Committable suggestion was skipped due to low confidence.
@@ -0,0 +1,45 @@ | |||
type TTSPlayer = { | |||
init: () => void; | |||
play: (audioBuffer: ArrayBuffer, onended: () => void | null) => Promise<void>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace null
with undefined
for onended
.
Using undefined
instead of null
for onended
avoids confusion and aligns with best practices.
Apply this diff to fix the issue:
- play: (audioBuffer: ArrayBuffer, onended: () => void | null) => Promise<void>;
+ play: (audioBuffer: ArrayBuffer, onended: () => void | undefined) => Promise<void>;
Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
play: (audioBuffer: ArrayBuffer, onended: () => void | null) => Promise<void>; | |
play: (audioBuffer: ArrayBuffer, onended: () => void | undefined) => Promise<void>; |
Tools
Biome
[error] 3-3: void is confusing inside a union type.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
audioContext.suspend(); | ||
}; | ||
|
||
const play = async (audioBuffer: ArrayBuffer, onended: () => void | null) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace null
with undefined
for onended
.
Using undefined
instead of null
for onended
avoids confusion and aligns with best practices.
Apply this diff to fix the issue:
- const play = async (audioBuffer: ArrayBuffer, onended: () => void | null) => {
+ const play = async (audioBuffer: ArrayBuffer, onended: () => void | undefined) => {
Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const play = async (audioBuffer: ArrayBuffer, onended: () => void | null) => { | |
const play = async (audioBuffer: ArrayBuffer, onended: () => void | undefined) => { |
Tools
Biome
[error] 16-16: void is confusing inside a union type.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
(config.engine = STTConfigValidator.engine( | ||
e.currentTarget.value, | ||
)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid assignments in expressions.
The use of assignments in expressions is confusing. Move the assignment out of the expression to improve readability.
Apply this diff to fix the issue:
- (config.engine = STTConfigValidator.engine(
- e.currentTarget.value,
- )),
+ {
+ config.engine = STTConfigValidator.engine(
+ e.currentTarget.value,
+ );
+ },
Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
(config.engine = STTConfigValidator.engine( | |
e.currentTarget.value, | |
)), | |
{ | |
config.engine = STTConfigValidator.engine( | |
e.currentTarget.value, | |
); | |
}, |
Tools
Biome
[error] 35-37: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
async start(): Promise<void> { | ||
this.listeningStatus = true; | ||
await this.recognitionInstance.start(); | ||
} | ||
|
||
async stop(): Promise<void> { | ||
this.listeningStatus = false; | ||
await this.recognitionInstance.stop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve error handling in the start
and stop
methods.
The start
and stop
methods should handle errors more gracefully. Consider adding try-catch blocks to handle potential errors.
Apply this diff to improve error handling:
async start(): Promise<void> {
+ try {
this.listeningStatus = true;
await this.recognitionInstance.start();
+ } catch (error) {
+ console.error("Error starting speech recognition:", error);
+ this.listeningStatus = false;
+ }
}
async stop(): Promise<void> {
+ try {
this.listeningStatus = false;
await this.recognitionInstance.stop();
+ } catch (error) {
+ console.error("Error stopping speech recognition:", error);
+ }
}
Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
async start(): Promise<void> { | |
this.listeningStatus = true; | |
await this.recognitionInstance.start(); | |
} | |
async stop(): Promise<void> { | |
this.listeningStatus = false; | |
await this.recognitionInstance.stop(); | |
async start(): Promise<void> { | |
try { | |
this.listeningStatus = true; | |
await this.recognitionInstance.start(); | |
} catch (error) { | |
console.error("Error starting speech recognition:", error); | |
this.listeningStatus = false; | |
} | |
} | |
async stop(): Promise<void> { | |
try { | |
this.listeningStatus = false; | |
await this.recognitionInstance.stop(); | |
} catch (error) { | |
console.error("Error stopping speech recognition:", error); | |
} | |
} |
checked={props.ttsConfig.enable} | ||
onChange={(e) => | ||
props.updateConfig( | ||
(config) => (config.enable = e.currentTarget.checked), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid assignments in expressions.
The use of assignments in expressions should be avoided as it can be confusing. Consider refactoring the code to separate assignments from expressions.
Apply this diff to avoid assignments in expressions:
props.updateConfig(
- (config) => (config.enable = e.currentTarget.checked),
+ (config) => { config.enable = e.currentTarget.checked; },
);
props.updateConfig(
- (config) => (config.engine = TTSConfigValidator.engine(e.currentTarget.value)),
+ (config) => { config.engine = TTSConfigValidator.engine(e.currentTarget.value); },
);
props.updateConfig(
- (config) => (config.model = TTSConfigValidator.model(e.currentTarget.value)),
+ (config) => { config.model = TTSConfigValidator.model(e.currentTarget.value); },
);
props.updateConfig(
- (config) => (config.voice = TTSConfigValidator.voice(e.currentTarget.value)),
+ (config) => { config.voice = TTSConfigValidator.voice(e.currentTarget.value); },
);
props.updateConfig(
- (config) => (config.speed = TTSConfigValidator.speed(e.currentTarget.valueAsNumber)),
+ (config) => { config.speed = TTSConfigValidator.speed(e.currentTarget.valueAsNumber); },
);
Also applies to: 53-55, 74-76, 96-98, 121-123
Tools
Biome
[error] 28-28: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
{/* <ListItem | ||
title={Locale.Settings.TTS.Autoplay.Title} | ||
subTitle={Locale.Settings.TTS.Autoplay.SubTitle} | ||
> | ||
<input | ||
type="checkbox" | ||
checked={props.ttsConfig.autoplay} | ||
onChange={(e) => | ||
props.updateConfig( | ||
(config) => (config.autoplay = e.currentTarget.checked), | ||
) | ||
} | ||
></input> | ||
</ListItem> */} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove or explain the commented-out code.
The commented-out code should be removed if it is no longer needed, or an explanation should be added to clarify its purpose.
Apply this diff to remove the commented-out code:
- {/* <ListItem
- title={Locale.Settings.TTS.Autoplay.Title}
- subTitle={Locale.Settings.TTS.Autoplay.SubTitle}
- >
- <input
- type="checkbox"
- checked={props.ttsConfig.autoplay}
- onChange={(e) =>
- props.updateConfig(
- (config) => (config.autoplay = e.currentTarget.checked),
- )
- }
- ></input>
- </ListItem> */}
Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
{/* <ListItem | |
title={Locale.Settings.TTS.Autoplay.Title} | |
subTitle={Locale.Settings.TTS.Autoplay.SubTitle} | |
> | |
<input | |
type="checkbox" | |
checked={props.ttsConfig.autoplay} | |
onChange={(e) => | |
props.updateConfig( | |
(config) => (config.autoplay = e.currentTarget.checked), | |
) | |
} | |
></input> | |
</ListItem> */} |
export class MsEdgeTTS { | ||
static OUTPUT_FORMAT = OUTPUT_FORMAT; | ||
private static TRUSTED_CLIENT_TOKEN = "6A5AA1D4EAFF4E9FB37E23D68491D6F4"; | ||
private static VOICES_URL = `https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=${MsEdgeTTS.TRUSTED_CLIENT_TOKEN}`; | ||
private static SYNTH_URL = `wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1?TrustedClientToken=${MsEdgeTTS.TRUSTED_CLIENT_TOKEN}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential security issue: Detected a Generic API Key.
The TRUSTED_CLIENT_TOKEN
might expose access to various services and sensitive operations.
Consider storing the token in a secure environment variable and accessing it securely.
Tools
Gitleaks
121-121: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
const accessStore = useAccessStore(); | ||
const [speechStatus, setSpeechStatus] = useState(false); | ||
const [speechLoading, setSpeechLoading] = useState(false); | ||
async function openaiSpeech(text: string) { | ||
if (speechStatus) { | ||
ttsPlayer.stop(); | ||
setSpeechStatus(false); | ||
} else { | ||
var api: ClientApi; | ||
api = new ClientApi(ModelProvider.GPT); | ||
const config = useAppConfig.getState(); | ||
setSpeechLoading(true); | ||
ttsPlayer.init(); | ||
let audioBuffer: ArrayBuffer; | ||
const { markdownToTxt } = require("markdown-to-txt"); | ||
const textContent = markdownToTxt(text); | ||
if (config.ttsConfig.engine !== DEFAULT_TTS_ENGINE) { | ||
const edgeVoiceName = accessStore.edgeVoiceName(); | ||
const tts = new MsEdgeTTS(); | ||
await tts.setMetadata( | ||
edgeVoiceName, | ||
OUTPUT_FORMAT.AUDIO_24KHZ_96KBITRATE_MONO_MP3, | ||
); | ||
audioBuffer = await tts.toArrayBuffer(textContent); | ||
} else { | ||
audioBuffer = await api.llm.speech({ | ||
model: config.ttsConfig.model, | ||
input: textContent, | ||
voice: config.ttsConfig.voice, | ||
speed: config.ttsConfig.speed, | ||
}); | ||
} | ||
setSpeechStatus(true); | ||
ttsPlayer | ||
.play(audioBuffer, () => { | ||
setSpeechStatus(false); | ||
}) | ||
.catch((e) => { | ||
console.error("[OpenAI Speech]", e); | ||
showToast(prettyObject(e)); | ||
setSpeechStatus(false); | ||
}) | ||
.finally(() => setSpeechLoading(false)); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use dynamic import for markdown-to-txt
.
The state variables and function are correctly implemented. However, the require
statement for markdown-to-txt
inside the function might cause issues in environments where require
is not available, such as ES modules.
Consider using dynamic import for markdown-to-txt
:
async function openaiSpeech(text: string) {
if (speechStatus) {
ttsPlayer.stop();
setSpeechStatus(false);
} else {
var api: ClientApi;
api = new ClientApi(ModelProvider.GPT);
const config = useAppConfig.getState();
setSpeechLoading(true);
ttsPlayer.init();
let audioBuffer: ArrayBuffer;
- const { markdownToTxt } = require("markdown-to-txt");
+ const { markdownToTxt } = await import("markdown-to-txt");
const textContent = markdownToTxt(text);
if (config.ttsConfig.engine !== DEFAULT_TTS_ENGINE) {
const edgeVoiceName = accessStore.edgeVoiceName();
const tts = new MsEdgeTTS();
await tts.setMetadata(
edgeVoiceName,
OUTPUT_FORMAT.AUDIO_24KHZ_96KBITRATE_MONO_MP3,
);
audioBuffer = await tts.toArrayBuffer(textContent);
} else {
audioBuffer = await api.llm.speech({
model: config.ttsConfig.model,
input: textContent,
voice: config.ttsConfig.voice,
speed: config.ttsConfig.speed,
});
}
setSpeechStatus(true);
ttsPlayer
.play(audioBuffer, () => {
setSpeechStatus(false);
})
.catch((e) => {
console.error("[OpenAI Speech]", e);
showToast(prettyObject(e));
setSpeechStatus(false);
})
.finally(() => setSpeechLoading(false));
}
}
Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const accessStore = useAccessStore(); | |
const [speechStatus, setSpeechStatus] = useState(false); | |
const [speechLoading, setSpeechLoading] = useState(false); | |
async function openaiSpeech(text: string) { | |
if (speechStatus) { | |
ttsPlayer.stop(); | |
setSpeechStatus(false); | |
} else { | |
var api: ClientApi; | |
api = new ClientApi(ModelProvider.GPT); | |
const config = useAppConfig.getState(); | |
setSpeechLoading(true); | |
ttsPlayer.init(); | |
let audioBuffer: ArrayBuffer; | |
const { markdownToTxt } = require("markdown-to-txt"); | |
const textContent = markdownToTxt(text); | |
if (config.ttsConfig.engine !== DEFAULT_TTS_ENGINE) { | |
const edgeVoiceName = accessStore.edgeVoiceName(); | |
const tts = new MsEdgeTTS(); | |
await tts.setMetadata( | |
edgeVoiceName, | |
OUTPUT_FORMAT.AUDIO_24KHZ_96KBITRATE_MONO_MP3, | |
); | |
audioBuffer = await tts.toArrayBuffer(textContent); | |
} else { | |
audioBuffer = await api.llm.speech({ | |
model: config.ttsConfig.model, | |
input: textContent, | |
voice: config.ttsConfig.voice, | |
speed: config.ttsConfig.speed, | |
}); | |
} | |
setSpeechStatus(true); | |
ttsPlayer | |
.play(audioBuffer, () => { | |
setSpeechStatus(false); | |
}) | |
.catch((e) => { | |
console.error("[OpenAI Speech]", e); | |
showToast(prettyObject(e)); | |
setSpeechStatus(false); | |
}) | |
.finally(() => setSpeechLoading(false)); | |
} | |
} | |
const accessStore = useAccessStore(); | |
const [speechStatus, setSpeechStatus] = useState(false); | |
const [speechLoading, setSpeechLoading] = useState(false); | |
async function openaiSpeech(text: string) { | |
if (speechStatus) { | |
ttsPlayer.stop(); | |
setSpeechStatus(false); | |
} else { | |
var api: ClientApi; | |
api = new ClientApi(ModelProvider.GPT); | |
const config = useAppConfig.getState(); | |
setSpeechLoading(true); | |
ttsPlayer.init(); | |
let audioBuffer: ArrayBuffer; | |
const { markdownToTxt } = await import("markdown-to-txt"); | |
const textContent = markdownToTxt(text); | |
if (config.ttsConfig.engine !== DEFAULT_TTS_ENGINE) { | |
const edgeVoiceName = accessStore.edgeVoiceName(); | |
const tts = new MsEdgeTTS(); | |
await tts.setMetadata( | |
edgeVoiceName, | |
OUTPUT_FORMAT.AUDIO_24KHZ_96KBITRATE_MONO_MP3, | |
); | |
audioBuffer = await tts.toArrayBuffer(textContent); | |
} else { | |
audioBuffer = await api.llm.speech({ | |
model: config.ttsConfig.model, | |
input: textContent, | |
voice: config.ttsConfig.voice, | |
speed: config.ttsConfig.speed, | |
}); | |
} | |
setSpeechStatus(true); | |
ttsPlayer | |
.play(audioBuffer, () => { | |
setSpeechStatus(false); | |
}) | |
.catch((e) => { | |
console.error("[OpenAI Speech]", e); | |
showToast(prettyObject(e)); | |
setSpeechStatus(false); | |
}) | |
.finally(() => setSpeechLoading(false)); | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- app/locales/en.ts (2 hunks)
Additional comments not posted (3)
app/locales/en.ts (3)
48-49
: LGTM!The new entries for
"Play"
and"Stop"
are correctly added under theActions
section.The code changes are approved.
493-513
: LGTM!The new section for TTS functionalities is correctly added with appropriate entries for enabling TTS, autoplay, model, voice, speed, and engine.
The code changes are approved.
514-523
: LGTM!The new section for STT functionalities is correctly added with appropriate entries for enabling STT and selecting the engine.
The code changes are approved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (8)
- app/client/platforms/alibaba.ts (2 hunks)
- app/client/platforms/anthropic.ts (2 hunks)
- app/client/platforms/baidu.ts (2 hunks)
- app/client/platforms/bytedance.ts (2 hunks)
- app/client/platforms/google.ts (2 hunks)
- app/client/platforms/iflytek.ts (2 hunks)
- app/client/platforms/moonshot.ts (2 hunks)
- app/client/platforms/tencent.ts (2 hunks)
Files skipped from review as they are similar to previous changes (7)
- app/client/platforms/alibaba.ts
- app/client/platforms/baidu.ts
- app/client/platforms/bytedance.ts
- app/client/platforms/google.ts
- app/client/platforms/iflytek.ts
- app/client/platforms/moonshot.ts
- app/client/platforms/tencent.ts
Additional comments not posted (2)
app/client/platforms/anthropic.ts (2)
83-85
: LGTM! Add a TODO comment.The placeholder implementation is acceptable for now. Consider adding a TODO comment to indicate that the method needs to be implemented.
speech(options: SpeechOptions): Promise<ArrayBuffer> { + // TODO: Implement speech method throw new Error("Method not implemented."); }
86-88
: LGTM! Add a TODO comment.The placeholder implementation is acceptable for now. Consider adding a TODO comment to indicate that the method needs to be implemented.
transcription(options: TranscriptionOptions): Promise<string> { + // TODO: Implement transcription method throw new Error("Method not implemented."); }
Your build has completed! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (3)
- app/client/api.ts (4 hunks)
- app/components/chat.tsx (11 hunks)
- app/components/tts-config.tsx (1 hunks)
Additional context used
Biome
app/components/tts-config.tsx
[error] 28-28: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 53-55: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 74-76: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 96-98: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
[error] 122-124: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
Additional comments not posted (14)
app/components/tts-config.tsx (3)
1-1
: Import statement is correct.The import statement correctly imports necessary modules and constants.
The code changes are approved.
28-28
: Avoid assignments in expressions.The use of assignments in expressions should be avoided as it can be confusing. Consider refactoring the code to separate assignments from expressions.
Apply this diff to avoid assignments in expressions:
props.updateConfig( - (config) => (config.enable = e.currentTarget.checked), + (config) => { config.enable = e.currentTarget.checked; }, ); props.updateConfig( - (config) => (config.engine = TTSConfigValidator.engine(e.currentTarget.value)), + (config) => { config.engine = TTSConfigValidator.engine(e.currentTarget.value); }, ); props.updateConfig( - (config) => (config.model = TTSConfigValidator.model(e.currentTarget.value)), + (config) => { config.model = TTSConfigValidator.model(e.currentTarget.value); }, ); props.updateConfig( - (config) => (config.voice = TTSConfigValidator.voice(e.currentTarget.value)), + (config) => { config.voice = TTSConfigValidator.voice(e.currentTarget.value); }, ); props.updateConfig( - (config) => (config.speed = TTSConfigValidator.speed(e.currentTarget.valueAsNumber)), + (config) => { config.speed = TTSConfigValidator.speed(e.currentTarget.valueAsNumber); }, );Also applies to: 53-55, 74-76, 96-98, 122-124
Tools
Biome
[error] 28-28: The assignment should not be in an expression.
The use of assignments in expressions is confusing.
Expressions are often considered as side-effect free.(lint/suspicious/noAssignInExpressions)
33-46
: Remove or explain the commented-out code.The commented-out code should be removed if it is no longer needed, or an explanation should be added to clarify its purpose.
Apply this diff to remove the commented-out code:
- {/* <ListItem - title={Locale.Settings.TTS.Autoplay.Title} - subTitle={Locale.Settings.TTS.Autoplay.SubTitle} - > - <input - type="checkbox" - checked={props.ttsConfig.autoplay} - onChange={(e) => - props.updateConfig( - (config) => (config.autoplay = e.currentTarget.checked), - ) - } - ></input> - </ListItem> */}app/client/api.ts (4)
23-23
: LGTM!The constant
TTSModels
is correctly defined.The code changes are approved.
52-59
: LGTM!The interface
SpeechOptions
is correctly defined and provides structured configurations for handling speech requests.The code changes are approved.
61-69
: LGTM!The interface
TranscriptionOptions
is correctly defined and provides structured configurations for handling transcription requests.The code changes are approved.
103-104
: LGTM!The abstract methods
speech
andtranscription
are correctly defined and enhance the class's functionality.The code changes are approved.
app/components/chat.tsx (7)
13-20
: LGTM!The new imports for various speech-related icons and APIs are correctly added and necessary for the new functionalities.
The code changes are approved.
Also applies to: 97-100, 117-124
548-550
: LGTM!The new state variables
isListening
,isTranscription
, andspeechApi
are correctly implemented and necessary for managing the speech recognition process.The code changes are approved.
552-563
: LGTM!The
useEffect
hook is correctly implemented and ensures the proper initialization of the speech API.The code changes are approved.
565-585
: LGTM!The functions
startListening
,stopListening
, andonRecognitionEnd
are correctly implemented and necessary for managing the speech recognition lifecycle.The code changes are approved.
1175-1216
: Use dynamic import formarkdown-to-txt
.The function is correctly implemented. However, the
require
statement formarkdown-to-txt
inside the function might cause issues in environments whererequire
is not available, such as ES modules.Consider using dynamic import for
markdown-to-txt
:async function openaiSpeech(text: string) { if (speechStatus) { ttsPlayer.stop(); setSpeechStatus(false); } else { var api: ClientApi; api = new ClientApi(ModelProvider.GPT); const config = useAppConfig.getState(); setSpeechLoading(true); ttsPlayer.init(); let audioBuffer: ArrayBuffer; - const { markdownToTxt } = require("markdown-to-txt"); + const { markdownToTxt } = await import("markdown-to-txt"); const textContent = markdownToTxt(text); if (config.ttsConfig.engine !== DEFAULT_TTS_ENGINE) { const edgeVoiceName = accessStore.edgeVoiceName(); const tts = new MsEdgeTTS(); await tts.setMetadata( edgeVoiceName, OUTPUT_FORMAT.AUDIO_24KHZ_96KBITRATE_MONO_MP3, ); audioBuffer = await tts.toArrayBuffer(textContent); } else { audioBuffer = await api.llm.speech({ model: config.ttsConfig.model, input: textContent, voice: config.ttsConfig.voice, speed: config.ttsConfig.speed, }); } setSpeechStatus(true); ttsPlayer .play(audioBuffer, () => { setSpeechStatus(false); }) .catch((e) => { console.error("[OpenAI Speech]", e); showToast(prettyObject(e)); setSpeechStatus(false); }) .finally(() => setSpeechLoading(false)); } }
811-819
: LGTM!The button for starting and stopping speech input is correctly implemented and enhances the component's functionality.
The code changes are approved.
1172-1174
: LGTM!The modifications to include the
openaiSpeech
function are correctly implemented and enhance the function's functionality.The code changes are approved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- app/locales/en.ts (3 hunks)
Files skipped from review as they are similar to previous changes (1)
- app/locales/en.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (4)
- app/api/common.ts (2 hunks)
- app/client/api.ts (5 hunks)
- app/client/platforms/openai.ts (3 hunks)
- app/utils/speech.ts (1 hunks)
Files skipped from review as they are similar to previous changes (2)
- app/client/platforms/openai.ts
- app/utils/speech.ts
Additional comments not posted (8)
app/api/common.ts (3)
99-99
: LGTM!The code change to dynamically retrieve the
Content-Type
header from the request, defaulting to"application/json"
if not specified, is approved. This enhances the flexibility of handling different content types in requests.
104-104
: LGTM!The code change to replace the hardcoded
"Content-Type": "application/json"
in thefetchOptions
with the newcontentType
variable is approved. This ensures that the fetch request uses the correct content type as specified by the incoming request.
Line range hint
121-149
: LGTM!The code changes are approved:
Updating the conditional check for processing the request body to verify that the
contentType
includes"json"
before proceeding with the body processing logic ensures that the function only attempts to clone and send the request body if the content type is appropriate, thereby preventing potential errors when handling non-JSON payloads.Introducing a check to refuse requests for models that are not allowed based on the server configuration enhances security and control over the usage of models.
app/client/api.ts (5)
23-23
: LGTM!The code changes are approved.
52-59
: LGTM!The code changes are approved.
61-69
: LGTM!The code changes are approved.
103-103
: LGTM!The code changes are approved.
104-104
: LGTM!The code changes are approved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Outside diff range and nitpick comments (1)
package.json (1)
35-35
: Looks good! Consider running a vulnerability scan.The addition of the
markdown-to-txt
dependency aligns with the PR objective of enhancing text processing capabilities. The version constraint^2.0.1
is reasonable as it allows for bug fixes and minor enhancements while avoiding potentially breaking changes in major versions.As a best practice, consider running a vulnerability scan on this new dependency to ensure it doesn't introduce any known security issues.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files ignored due to path filters (1)
yarn.lock
is excluded by!**/yarn.lock
,!**/*.lock
Files selected for processing (12)
- app/client/api.ts (4 hunks)
- app/client/platforms/anthropic.ts (2 hunks)
- app/client/platforms/moonshot.ts (2 hunks)
- app/client/platforms/openai.ts (3 hunks)
- app/components/chat.tsx (11 hunks)
- app/constant.ts (3 hunks)
- app/layout.tsx (1 hunks)
- app/locales/cn.ts (3 hunks)
- app/locales/en.ts (3 hunks)
- app/locales/index.ts (1 hunks)
- app/store/config.ts (3 hunks)
- package.json (2 hunks)
Files skipped from review due to trivial changes (1)
- app/layout.tsx
Additional comments not posted (44)
app/locales/index.ts (3)
137-159
: LGTM!The introduction of the
DEFAULT_STT_LANG
constant and theSTT_LANG_MAP
record enhances the application's support for speech-to-text functionality in multiple languages. The mappings ensure that the appropriate language is used for speech-to-text operations based on the user's selected language.
161-167
: LGTM!The
getSTTLang()
function provides a convenient and consistent way to retrieve the appropriate speech-to-text language based on the user's selected language in the application. The error handling ensures a default language is returned if the lookup fails, preventing potential issues.
138-139
: This code segment has already been reviewed in a previous comment.app/store/config.ts (8)
8-15
: LGTM!The addition of default constants for STT and TTS configurations is a good practice. It provides a centralized location for defining default values and promotes consistency across the codebase.
22-26
: LGTM!Defining new types for TTS models, voices, engines, and STT engines based on the default constants is an excellent approach. It ensures type safety and prevents invalid values from being assigned to these configurations.
84-96
: LGTM!The introduction of
ttsConfig
andsttConfig
sections in theDEFAULT_CONFIG
object is a great addition. It allows for fine-grained control over TTS and STT functionalities, enabling users to customize their experience based on their preferences.
102-103
: LGTM!Defining separate types
TTSConfig
andSTTConfig
based on the corresponding sections in theChatConfig
type is a good practice. It allows for type-safe access to the TTS and STT configuration sections and improves code readability.
118-131
: LGTM!The introduction of the
TTSConfigValidator
object is a great addition to ensure the validity of TTS configuration values. The validation functions provide type safety and enforce constraints on the assigned values, preventing invalid configurations from being used.
133-138
: LGTM!The addition of the
STTConfigValidator
object with a validation function for STT engine is a good practice. It ensures type safety and prevents invalid values from being assigned to the STT engine configuration.
Line range hint
1-275
: Excellent work!The changes made in this file significantly enhance the application's capabilities in handling TTS and STT configurations. The introduction of default constants, types, and validation functions provides a robust and type-safe way to manage these configurations.
The code is well-structured, follows best practices, and aligns with the existing codebase. The AI-generated summary accurately summarizes the key aspects of the changes made.
Overall, these modifications lay a solid foundation for integrating TTS and STT functionalities into the application.
84-96
: Verify the usage of validation functions.The addition of
ttsConfig
andsttConfig
sections in theDEFAULT_CONFIG
object, along with the corresponding validation functions inTTSConfigValidator
andSTTConfigValidator
, is a great approach to ensure the validity of TTS and STT configurations.However, it's important to verify that the validation functions are being used consistently whenever TTS and STT configurations are modified or accessed throughout the codebase. This ensures that invalid values cannot be assigned and helps maintain the integrity of the configurations.
Run the following script to verify the usage of validation functions:
Also applies to: 118-138
Verification successful
Validation functions are used correctly and consistently.
After a thorough analysis of the codebase, I can confirm that the validation functions for TTS and STT configurations are being used appropriately and consistently. Here are the key findings:
TTS Configuration:
TTSConfigValidator
is used in thetts-config.tsx
component to validate all configuration updates (engine, model, voice, and speed).- The validator is applied whenever the user modifies TTS settings through the UI.
STT Configuration:
STTConfigValidator
is used in thestt-config.tsx
component to validate the engine configuration update.- The validator is applied when the user changes the STT engine through the UI.
Both validators are properly defined in
config.ts
and imported where needed.This implementation ensures that invalid values cannot be assigned to the configurations, maintaining the integrity of the TTS and STT settings throughout the application.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that validation functions are used when modifying or accessing TTS and STT configurations. # Test: Search for usages of `ttsConfig` and `sttConfig` properties. # Expect: Validation functions from `TTSConfigValidator` and `STTConfigValidator` are used. rg --type typescript -A 5 $'ttsConfig|sttConfig'Length of output: 84
Script:
#!/bin/bash # Description: Search for usages of TTS and STT configurations in TypeScript files # Search for ttsConfig and its properties echo "Searching for ttsConfig usage:" rg -g '*.{ts,tsx}' -i '(ttsConfig|ttsConfig\.(enable|autoplay|engine|model|voice|speed))' -A 5 echo "\nSearching for sttConfig usage:" rg -g '*.{ts,tsx}' -i '(sttConfig|sttConfig\.(enable|engine))' -A 5 echo "\nSearching for TTSConfigValidator usage:" rg -g '*.{ts,tsx}' 'TTSConfigValidator' -A 5 echo "\nSearching for STTConfigValidator usage:" rg -g '*.{ts,tsx}' 'STTConfigValidator' -A 5Length of output: 16434
app/client/platforms/moonshot.ts (1)
29-30
: LGTM!The import statement for
SpeechOptions
andTranscriptionOptions
types is correct. It indicates that theMoonshotApi
class will likely use these types for speech and transcription related functionalities.app/client/api.ts (5)
29-29
: LGTM!The constant declaration is clear and follows the existing naming convention.
58-65
: LGTM!The
SpeechOptions
interface provides a clear structure for specifying speech synthesis options. The property names are descriptive and the types are appropriate.
67-75
: LGTM!The
TranscriptionOptions
interface provides a clear structure for specifying audio transcription options. The property names are descriptive and the types are appropriate.
111-112
: LGTM!The
speech
andtranscription
abstract methods in theLLMApi
class provide a clear contract for implementing speech synthesis and audio transcription functionality. The parameter and return types are appropriate.
231-240
: LGTM!The modifications to the
getHeaders
function provide flexibility in header management. The conditional check ensures that default headers are only included when necessary, and the constructed headers object follows the existing structure.app/client/platforms/anthropic.ts (2)
90-92
: LGTM!The
speech
method is correctly added to theClaudeApi
class, following theLLMApi
interface. The method is not implemented yet, which is fine for now. Please remember to implement the method in the future.
93-95
: LGTM!The
transcription
method is correctly added to theClaudeApi
class, following theLLMApi
interface. The method is not implemented yet, which is fine for now. Please remember to implement the method in the future.app/constant.ts (11)
155-155
: LGTM!The
SpeechPath
constant is correctly defined and follows the naming convention of other OpenAI API paths.
156-156
: LGTM!The
TranscriptionPath
constant is correctly defined and follows the naming convention of other OpenAI API paths.
263-263
: LGTM!The
DEFAULT_TTS_ENGINE
constant is correctly defined and clearly indicates the default TTS engine being used.
264-264
: LGTM!The
DEFAULT_TTS_ENGINES
constant is correctly defined as an array and includes the available TTS engines.
265-265
: LGTM!The
DEFAULT_TTS_MODEL
constant is correctly defined and clearly indicates the default TTS model being used.
266-266
: LGTM!The
DEFAULT_TTS_VOICE
constant is correctly defined and clearly indicates the default TTS voice being used.
267-267
: LGTM!The
DEFAULT_TTS_MODELS
constant is correctly defined as an array and includes the available TTS models.
268-275
: LGTM!The
DEFAULT_TTS_VOICES
constant is correctly defined as an array and includes the available TTS voice options.
277-277
: LGTM!The
DEFAULT_STT_ENGINE
constant is correctly defined and clearly indicates the default STT engine being used.
278-278
: LGTM!The
DEFAULT_STT_ENGINES
constant is correctly defined as an array and includes the available STT engines.
279-279
: LGTM!The
FIREFOX_DEFAULT_STT_ENGINE
constant is correctly defined and clearly indicates the default STT engine being used for Firefox.app/client/platforms/openai.ts (3)
89-89
: Verify the purpose and usage of themodel
parameter.The function signature has been modified to include an optional
model
parameter. However, themodel
parameter is not being used within the function body.Please clarify the intended purpose of the
model
parameter and ensure that it is being utilized correctly within the function implementation.
152-188
: LGTM!The
speech
function implementation looks good:
- It correctly constructs the request payload based on the provided
SpeechOptions
.- The usage of
AbortController
and timeout mechanism ensures proper handling of request cancellation.- The function sends the request to the appropriate OpenAI Speech API endpoint and returns the response as an
ArrayBuffer
.The function enhances the
ChatGPTApi
class with speech synthesis capabilities.
190-229
: LGTM!The
transcription
function implementation looks good:
- It correctly constructs the
FormData
object based on the providedTranscriptionOptions
.- The function appends the audio file and various optional parameters to the
FormData
object.- The usage of
AbortController
and timeout mechanism ensures proper handling of request cancellation.- The function sends the request to the appropriate OpenAI Transcription API endpoint and extracts the transcribed text from the response.
The function enhances the
ChatGPTApi
class with audio transcription capabilities.app/locales/cn.ts (4)
49-50
: LGTM!The addition of the "Speech" and "StopSpeech" localization strings is consistent with the introduction of speech-related functionalities mentioned in the PR summary. The placement of these strings under the "Actions" section aligns with the existing structure.
84-85
: LGTM!The addition of the "StartSpeak" and "StopSpeak" localization strings aligns with the introduction of speech-related functionalities mentioned in the PR summary. The placement of these strings at the root level of the "Chat" section suggests that they are top-level actions related to speech, which is appropriate.
503-522
: LGTM!The addition of the "TTS" configuration section under the "Settings" section is a great enhancement. It provides users with comprehensive control over text-to-speech settings, including options for enabling TTS, autoplay, model selection, engine selection, voice selection, and speed adjustment. The changes align with the introduction of a dedicated TTS configuration object mentioned in the PR summary.
523-532
: LGTM!The addition of the "STT" configuration section under the "Settings" section is a valuable enhancement. It provides users with control over speech-to-text settings, including options for enabling STT and selecting the conversion engine. The changes align with the introduction of a dedicated STT configuration object mentioned in the PR summary.
app/locales/en.ts (3)
50-51
: LGTM!The added key-value pairs for
Speech
andStopSpeech
actions are consistent with the existing naming convention and align with the PR objective of introducing TTS and STT functionalities.
85-86
: LGTM!The added key-value pairs for
StartSpeak
andStopSpeak
are consistent with the existing naming convention and align with the PR objective of introducing TTS and STT functionalities.
509-539
: Looks good!The added
TTS
andSTT
objects provide comprehensive configuration options for the text-to-speech and speech-to-text functionalities. The properties within these objects are consistent with the existing naming convention and align perfectly with the PR objective and the AI-generated summary.app/components/chat.tsx (4)
559-595
: LGTM! The speech recognition feature is correctly implemented.The speech recognition feature enhances the user experience by allowing voice input. The feature is correctly integrated with the existing chat input and user input state management. The implementation is compatible with different browsers and speech recognition engines.
1257-1298
: LGTM! The text-to-speech feature is correctly implemented.The text-to-speech feature enhances the user experience by allowing the chat messages to be read aloud. The feature is correctly integrated with the existing chat message rendering and configuration management. The implementation supports different TTS engines and configurations for flexibility and compatibility.
1839-1857
: LGTM! The text-to-speech feature is correctly integrated with the chat message actions.The text-to-speech feature is correctly integrated with the existing chat message actions and rendering. The feature enhances the user experience by allowing the user to start and stop speech for each chat message. The implementation is correctly integrated with the existing TTS configuration management.
1976-1976
: LGTM! ThesetUserInput
prop is correctly added to theChatActions
function.The
setUserInput
prop is necessary to correctly integrate the speech recognition feature with the existing user input management. The prop is correctly passed down from the parent component and used to set the user input when the speech recognition ends.
speech(options: SpeechOptions): Promise<ArrayBuffer> { | ||
throw new Error("Method not implemented."); | ||
} | ||
transcription(options: TranscriptionOptions): Promise<string> { | ||
throw new Error("Method not implemented."); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implement the methods before merging.
The speech
and transcription
method signatures look good:
speech
acceptsSpeechOptions
and returnsPromise<ArrayBuffer>
, which is suitable for speech synthesis.transcription
takesTranscriptionOptions
and returnsPromise<string>
, which is appropriate for speech transcription.
However, please ensure that the methods are fully implemented before merging these changes to avoid unexpected errors in the application.
π» εζ΄η±»ε | Change Type
π εζ΄θ―΄ζ | Description of Change
π θ‘₯ε δΏ‘ζ― | Additional Information
Summary by CodeRabbit
New Features
Bug Fixes
Documentation