feat: audio to message

This commit is contained in:
Dogtiti 2024-11-06 22:30:02 +08:00
parent f6e1f8398b
commit a4941521d0
1 changed files with 24 additions and 34 deletions

View File

@ -6,9 +6,14 @@ import PowerIcon from "@/app/icons/power.svg";
import styles from "./realtime-chat.module.scss"; import styles from "./realtime-chat.module.scss";
import clsx from "clsx"; import clsx from "clsx";
import { useState, useRef, useCallback, useEffect } from "react"; import { useState, useRef, useEffect } from "react";
import { useAccessStore, useChatStore, ChatMessage } from "@/app/store"; import {
useAccessStore,
useChatStore,
ChatMessage,
createMessage,
} from "@/app/store";
import { IconButton } from "@/app/components/button"; import { IconButton } from "@/app/components/button";
@ -37,6 +42,7 @@ export function RealtimeChat({
const currentUserMessage = useRef<ChatMessage | null>(); const currentUserMessage = useRef<ChatMessage | null>();
const accessStore = useAccessStore.getState(); const accessStore = useAccessStore.getState();
const chatStore = useChatStore(); const chatStore = useChatStore();
const session = chatStore.currentSession();
const [isRecording, setIsRecording] = useState(false); const [isRecording, setIsRecording] = useState(false);
const [isConnected, setIsConnected] = useState(false); const [isConnected, setIsConnected] = useState(false);
@ -121,29 +127,19 @@ export function RealtimeChat({
const handleResponse = async (response: RTResponse) => { const handleResponse = async (response: RTResponse) => {
for await (const item of response) { for await (const item of response) {
if (item.type === "message" && item.role === "assistant") { if (item.type === "message" && item.role === "assistant") {
const message = { const botMessage = createMessage({
type: item.role, role: item.role,
content: "", content: "",
}; });
// setMessages((prevMessages) => [...prevMessages, message]);
for await (const content of item) { for await (const content of item) {
if (content.type === "text") { if (content.type === "text") {
for await (const text of content.textChunks()) { for await (const text of content.textChunks()) {
message.content += text; botMessage.content += text;
// setMessages((prevMessages) => {
// prevMessages[prevMessages.length - 1].content = message.content;
// return [...prevMessages];
// });
} }
} else if (content.type === "audio") { } else if (content.type === "audio") {
const textTask = async () => { const textTask = async () => {
for await (const text of content.transcriptChunks()) { for await (const text of content.transcriptChunks()) {
message.content += text; botMessage.content += text;
// setMessages((prevMessages) => {
// prevMessages[prevMessages.length - 1].content =
// message.content;
// return [...prevMessages];
// });
} }
}; };
const audioTask = async () => { const audioTask = async () => {
@ -153,6 +149,10 @@ export function RealtimeChat({
} }
}; };
await Promise.all([textTask(), audioTask()]); await Promise.all([textTask(), audioTask()]);
chatStore.updateTargetSession(session, (session) => {
botMessage.date = new Date().toLocaleString();
session.messages = session.messages.concat([botMessage]);
});
} }
} }
} }
@ -162,13 +162,13 @@ export function RealtimeChat({
const handleInputAudio = async (item: RTInputAudioItem) => { const handleInputAudio = async (item: RTInputAudioItem) => {
audioHandlerRef.current?.stopStreamingPlayback(); audioHandlerRef.current?.stopStreamingPlayback();
await item.waitForCompletion(); await item.waitForCompletion();
// setMessages((prevMessages) => [ const userMessage = createMessage({
// ...prevMessages, role: "user",
// { content: item.transcription,
// type: "user", });
// content: item.transcription || "", chatStore.updateTargetSession(session, (session) => {
// }, session.messages = session.messages.concat([userMessage]);
// ]); });
}; };
const toggleRecording = async () => { const toggleRecording = async () => {
@ -407,15 +407,6 @@ export function RealtimeChat({
// }; // };
// }, [isRecording.current]); // }, [isRecording.current]);
const handleStartVoice = useCallback(() => {
onStartVoice?.();
handleConnect();
}, []);
const handlePausedVoice = () => {
onPausedVoice?.();
};
const handleClose = () => { const handleClose = () => {
onClose?.(); onClose?.();
disconnect(); disconnect();
@ -460,7 +451,6 @@ export function RealtimeChat({
<IconButton <IconButton
icon={<Close24Icon />} icon={<Close24Icon />}
onClick={handleClose} onClick={handleClose}
disabled={!isConnected}
bordered bordered
shadow shadow
/> />