-
Notifications
You must be signed in to change notification settings - Fork 59.9k
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
test stt #5634
base: main
Are you sure you want to change the base?
test stt #5634
Changes from 7 commits
ec28338
76faff0
8ec4df4
6e38569
d7eee52
5999604
80a7a1d
43d3824
5e514c5
b91c224
7475519
f0b9068
b5a5558
0ea650d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,11 @@ | ||
import { Anthropic, ApiPath } from "@/app/constant"; | ||
import { ChatOptions, getHeaders, LLMApi, SpeechOptions } from "../api"; | ||
import { | ||
ChatOptions, | ||
getHeaders, | ||
LLMApi, | ||
SpeechOptions, | ||
TranscriptionOptions, | ||
} from "../api"; | ||
import { | ||
useAccessStore, | ||
useAppConfig, | ||
|
@@ -77,6 +83,10 @@ export class ClaudeApi implements LLMApi { | |
throw new Error("Method not implemented."); | ||
} | ||
|
||
transcription(options: TranscriptionOptions): Promise<string> { | ||
throw new Error("Method not implemented."); | ||
} | ||
Comment on lines
+86
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implement the The To complete this feature:
Would you like assistance in implementing this method or creating a GitHub issue to track this task? |
||
|
||
extractMessage(res: any) { | ||
console.log("[Response] claude response: ", res); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import { | |
LLMModel, | ||
MultimodalContent, | ||
SpeechOptions, | ||
TranscriptionOptions, | ||
} from "../api"; | ||
import Locale from "../../locales"; | ||
import { | ||
|
@@ -81,6 +82,10 @@ export class ErnieApi implements LLMApi { | |
throw new Error("Method not implemented."); | ||
} | ||
|
||
transcription(options: TranscriptionOptions): Promise<string> { | ||
throw new Error("Method not implemented."); | ||
} | ||
Comment on lines
+85
to
+87
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implement the The Would you like assistance in implementing the |
||
|
||
async chat(options: ChatOptions) { | ||
const messages = options.messages.map((v) => ({ | ||
// "error_code": 336006, "error_msg": "the role of message with even index in the messages must be user or function", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ import { | |
LLMApi, | ||
LLMModel, | ||
SpeechOptions, | ||
TranscriptionOptions, | ||
} from "../api"; | ||
import Locale from "../../locales"; | ||
import { | ||
|
@@ -64,6 +65,10 @@ export class SparkApi implements LLMApi { | |
throw new Error("Method not implemented."); | ||
} | ||
|
||
transcription(options: TranscriptionOptions): Promise<string> { | ||
throw new Error("Method not implemented."); | ||
} | ||
Comment on lines
+68
to
+70
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implement the transcription method. The To complete this feature:
Would you like assistance in implementing this method or creating a task to track its implementation? |
||
|
||
async chat(options: ChatOptions) { | ||
const messages: ChatOptions["messages"] = []; | ||
for (const v of options.messages) { | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -34,6 +34,7 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
LLMUsage, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
MultimodalContent, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SpeechOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
TranscriptionOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} from "../api"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import Locale from "../../locales"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { getClientConfig } from "@/app/config/client"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -180,6 +181,47 @@ export class ChatGPTApi implements LLMApi { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async transcription(options: TranscriptionOptions): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const formData = new FormData(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
formData.append("file", options.file, "audio.wav"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
formData.append("model", options.model ?? "whisper-1"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (options.language) formData.append("language", options.language); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (options.prompt) formData.append("prompt", options.prompt); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (options.response_format) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
formData.append("response_format", options.response_format); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (options.temperature) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
formData.append("temperature", options.temperature.toString()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log("[Request] openai audio transcriptions payload: ", options); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const controller = new AbortController(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
options.onController?.(controller); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const path = this.path(OpenaiPath.TranscriptionPath); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const headers = getHeaders(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const payload = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
method: "POST", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
body: formData, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
signal: controller.signal, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
headers: headers, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// make a fetch request | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const requestTimeoutId = setTimeout( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
() => controller.abort(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
REQUEST_TIMEOUT_MS, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const res = await fetch(path, payload); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
clearTimeout(requestTimeoutId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const json = await res.json(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return json.text; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+215
to
+218
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add response status check before parsing JSON In lines 214-217, the code attempts to parse the JSON response without verifying if the request was successful. If the request fails, Consider checking const res = await fetch(path, payload);
clearTimeout(requestTimeoutId);
+ if (!res.ok) {
+ const errorText = await res.text();
+ console.error(`[Response] Transcription request failed: ${errorText}`);
+ throw new Error(`Transcription request failed with status ${res.status}`);
+ }
const json = await res.json();
return json.text; 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log("[Request] failed to make a audio transcriptions request", e); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
throw e; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+184
to
+223
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance error handling and response parsing in the The implementation of the
I acknowledge the existing comment about these issues. To address them, consider applying the following improvements:
} catch (e) {
- console.log("[Request] failed to make a audio transcriptions request", e);
- throw e;
+ console.error("[Request] failed to make an audio transcriptions request", e);
+ throw new Error(`Transcription request failed: ${e.message}`);
}
const res = await fetch(path, payload);
clearTimeout(requestTimeoutId);
+if (!res.ok) {
+ throw new Error(`Transcription request failed with status ${res.status}`);
+}
const json = await res.json();
-return json.text;
+return json.text ?? '';
const payload = {
method: "POST",
body: formData,
signal: controller.signal,
- headers: headers,
+ headers,
}; These changes will improve the robustness and reliability of the 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async chat(options: ChatOptions) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const modelConfig = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
...useAppConfig.getState().modelConfig, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ import { | |
LLMModel, | ||
MultimodalContent, | ||
SpeechOptions, | ||
TranscriptionOptions, | ||
} from "../api"; | ||
import Locale from "../../locales"; | ||
import { | ||
|
@@ -93,6 +94,10 @@ export class HunyuanApi implements LLMApi { | |
throw new Error("Method not implemented."); | ||
} | ||
|
||
transcription(options: TranscriptionOptions): Promise<string> { | ||
throw new Error("Method not implemented."); | ||
} | ||
Comment on lines
96
to
+99
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider implementing both speech and transcription methods Both the Would you like assistance in drafting implementations for both methods? This would ensure the full functionality of the new feature. |
||
|
||
async chat(options: ChatOptions) { | ||
const visionModel = isVisionModel(options.config.model); | ||
const messages = options.messages.map((v, index) => ({ | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -10,6 +10,8 @@ import React, { | |||||||||||||||||||||||
} from "react"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
import SendWhiteIcon from "../icons/send-white.svg"; | ||||||||||||||||||||||||
import VoiceOpenIcon from "../icons/vioce-open.svg"; | ||||||||||||||||||||||||
import VoiceCloseIcon from "../icons/vioce-close.svg"; | ||||||||||||||||||||||||
Comment on lines
+13
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix typo in icon file paths There's a typo in the file paths for the newly imported voice icons. "vioce" should be "voice". Please apply the following changes: -import VoiceOpenIcon from "../icons/vioce-open.svg";
-import VoiceCloseIcon from "../icons/vioce-close.svg";
+import VoiceOpenIcon from "../icons/voice-open.svg";
+import VoiceCloseIcon from "../icons/voice-close.svg"; 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
import BrainIcon from "../icons/brain.svg"; | ||||||||||||||||||||||||
import RenameIcon from "../icons/rename.svg"; | ||||||||||||||||||||||||
import ExportIcon from "../icons/share.svg"; | ||||||||||||||||||||||||
|
@@ -72,6 +74,7 @@ import { | |||||||||||||||||||||||
isDalle3, | ||||||||||||||||||||||||
showPlugins, | ||||||||||||||||||||||||
safeLocalStorage, | ||||||||||||||||||||||||
isFirefox, | ||||||||||||||||||||||||
} from "../utils"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
import { uploadImage as uploadImageRemote } from "@/app/utils/chat"; | ||||||||||||||||||||||||
|
@@ -98,7 +101,9 @@ import { | |||||||||||||||||||||||
import { useNavigate } from "react-router-dom"; | ||||||||||||||||||||||||
import { | ||||||||||||||||||||||||
CHAT_PAGE_SIZE, | ||||||||||||||||||||||||
DEFAULT_STT_ENGINE, | ||||||||||||||||||||||||
DEFAULT_TTS_ENGINE, | ||||||||||||||||||||||||
FIREFOX_DEFAULT_STT_ENGINE, | ||||||||||||||||||||||||
ModelProvider, | ||||||||||||||||||||||||
Path, | ||||||||||||||||||||||||
REQUEST_TIMEOUT_MS, | ||||||||||||||||||||||||
|
@@ -118,6 +123,7 @@ import { MultimodalContent } from "../client/api"; | |||||||||||||||||||||||
const localStorage = safeLocalStorage(); | ||||||||||||||||||||||||
import { ClientApi } from "../client/api"; | ||||||||||||||||||||||||
import { createTTSPlayer } from "../utils/audio"; | ||||||||||||||||||||||||
import { OpenAITranscriptionApi, WebTranscriptionApi } from "../utils/speech"; | ||||||||||||||||||||||||
import { MsEdgeTTS, OUTPUT_FORMAT } from "../utils/ms_edge_tts"; | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
const ttsPlayer = createTTSPlayer(); | ||||||||||||||||||||||||
|
@@ -364,6 +370,7 @@ export function ChatAction(props: { | |||||||||||||||||||||||
text: string; | ||||||||||||||||||||||||
icon: JSX.Element; | ||||||||||||||||||||||||
onClick: () => void; | ||||||||||||||||||||||||
recording?: boolean; | ||||||||||||||||||||||||
}) { | ||||||||||||||||||||||||
const iconRef = useRef<HTMLDivElement>(null); | ||||||||||||||||||||||||
const textRef = useRef<HTMLDivElement>(null); | ||||||||||||||||||||||||
|
@@ -372,7 +379,7 @@ export function ChatAction(props: { | |||||||||||||||||||||||
icon: 16, | ||||||||||||||||||||||||
}); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
function updateWidth() { | ||||||||||||||||||||||||
function updateWidth(recording?: boolean) { | ||||||||||||||||||||||||
if (!iconRef.current || !textRef.current) return; | ||||||||||||||||||||||||
const getWidth = (dom: HTMLDivElement) => dom.getBoundingClientRect().width; | ||||||||||||||||||||||||
const textWidth = getWidth(textRef.current); | ||||||||||||||||||||||||
|
@@ -546,6 +553,46 @@ export function ChatActions(props: { | |||||||||||||||||||||||
} | ||||||||||||||||||||||||
}, [chatStore, currentModel, models]); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
const [isListening, setIsListening] = useState(false); | ||||||||||||||||||||||||
const [isTranscription, setIsTranscription] = useState(false); | ||||||||||||||||||||||||
const [speechApi, setSpeechApi] = useState<any>(null); | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider using a more specific type for speechApi state The - const [speechApi, setSpeechApi] = useState<any>(null);
+ const [speechApi, setSpeechApi] = useState<WebTranscriptionApi | OpenAITranscriptionApi | null>(null); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
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), | ||||||||||||||||||||||||
), | ||||||||||||||||||||||||
); | ||||||||||||||||||||||||
}, []); | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useEffect hook for initializing speech recognition. This hook initializes the speech recognition API based on the configured engine. It uses a Firefox-specific engine if the browser is Firefox. However, there's a potential issue: The - useEffect(() => {
+ 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]); Also, make sure
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
const startListening = async () => { | ||||||||||||||||||||||||
showToast(Locale.Chat.StartSpeak); | ||||||||||||||||||||||||
if (speechApi) { | ||||||||||||||||||||||||
await speechApi.start(); | ||||||||||||||||||||||||
setIsListening(true); | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
const stopListening = async () => { | ||||||||||||||||||||||||
if (speechApi) { | ||||||||||||||||||||||||
if (config.sttConfig.engine !== DEFAULT_STT_ENGINE) | ||||||||||||||||||||||||
setIsTranscription(true); | ||||||||||||||||||||||||
await speechApi.stop(); | ||||||||||||||||||||||||
setIsListening(false); | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
showToast(Locale.Chat.CloseSpeak); | ||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
const onRecognitionEnd = (finalTranscript: string) => { | ||||||||||||||||||||||||
console.log(finalTranscript); | ||||||||||||||||||||||||
if (finalTranscript) props.setUserInput(finalTranscript); | ||||||||||||||||||||||||
if (config.sttConfig.engine !== DEFAULT_STT_ENGINE) | ||||||||||||||||||||||||
setIsTranscription(false); | ||||||||||||||||||||||||
}; | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove console.log in production code There's a const onRecognitionEnd = (finalTranscript: string) => {
- console.log(finalTranscript);
if (finalTranscript) props.setUserInput(finalTranscript);
if (config.sttConfig.engine !== DEFAULT_STT_ENGINE)
setIsTranscription(false);
}; 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||
<div className={styles["chat-input-actions"]}> | ||||||||||||||||||||||||
{couldStop && ( | ||||||||||||||||||||||||
|
@@ -780,6 +827,17 @@ export function ChatActions(props: { | |||||||||||||||||||||||
icon={<ShortcutkeyIcon />} | ||||||||||||||||||||||||
/> | ||||||||||||||||||||||||
)} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
{config.sttConfig.enable && ( | ||||||||||||||||||||||||
<ChatAction | ||||||||||||||||||||||||
onClick={async () => | ||||||||||||||||||||||||
isListening ? await stopListening() : await startListening() | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
text={isListening ? Locale.Chat.StopSpeak : Locale.Chat.StartSpeak} | ||||||||||||||||||||||||
icon={isListening ? <VoiceOpenIcon /> : <VoiceCloseIcon />} | ||||||||||||||||||||||||
recording={isListening} | ||||||||||||||||||||||||
/> | ||||||||||||||||||||||||
)} | ||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||
); | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
@@ -1505,7 +1563,7 @@ function _Chat() { | |||||||||||||||||||||||
setAttachImages(images); | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
// 快捷键 shortcut keys | ||||||||||||||||||||||||
// 快捷键 | ||||||||||||||||||||||||
const [showShortcutKeyModal, setShowShortcutKeyModal] = useState(false); | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
useEffect(() => { | ||||||||||||||||||||||||
|
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
transcription
method.The
transcription
method is currently a placeholder. To complete this feature:TranscriptionOptions
interface.Would you like assistance in implementing the
transcription
method or creating a GitHub issue to track this task?