11"use client" ;
22
3- import CodeEditorView , {
4- CodeEditorViewRef ,
5- } from "@/components/views/code-editor-view" ;
3+ import { CodeEditorViewRef } from "@/components/views/code-editor-view" ;
64import { useMicVAD , utils } from "@/lib/hooks/use-mic-vad" ;
7- import { BaseLLM , getModelLLM } from "@/lib/llm/llm" ;
8- import { BaseSTT , getModelSTT } from "@/lib/stt/stt" ;
5+ import { BaseLLM } from "@/lib/llm/llm" ;
6+ import { BaseSTT } from "@/lib/stt/stt" ;
97import { useContext , useEffect , useRef , useState } from "react" ;
108import toast from "react-hot-toast" ;
119import { CodeEditorAgent } from "@/lib/agent/code-editor-agent" ;
12- import { BaseTTS , getModelTTS } from "@/lib/tts/tts" ;
13- import AgentChatTerminalView from "@/components/views/agent-chat-terminal-view" ;
14- import { AnimatePresence , motion } from "framer-motion" ;
15- import { ViewDocument , ViewRef } from "@/lib/types" ;
10+ import { BaseTTS } from "@/lib/tts/tts" ;
1611import EditorToolbar from "@/components/editor-toolbar" ;
1712import { EditorContext } from "@/components/providers/editor-context-provider" ;
13+ import ViewDisplayArea from "@/components/view-display-area" ;
1814
1915export default function Home ( ) {
20- const [ isCanvasReady , setIsCanvasReady ] = useState ( false ) ;
21-
22- // const viewMap = useRef<Map<string, ViewRef | null>>(new Map());
2316 const editorContext = useContext ( EditorContext ) ;
2417
25- const sttModelRef = useRef < BaseSTT | undefined > ( undefined ) ;
26- const llmModelRef = useRef < BaseLLM | undefined > ( undefined ) ;
27- const ttsModelRef = useRef < BaseTTS | undefined > ( undefined ) ;
28-
2918 // TODO: Use a timer to stop recorder if no speech is detected for more than 30 seconds
30-
31- const [ isProcessing , setIsProcessing ] = useState ( false ) ;
19+ const isProcessingRef = useRef ( false ) ;
3220 const vad = useMicVAD ( {
3321 startOnLoad : false ,
3422 ortConfig ( ort ) {
@@ -37,31 +25,48 @@ export default function Home() {
3725 workletURL : "/vad/vad.worklet.bundle.min.js" ,
3826 modelURL : "/vad/silero_vad.onnx" ,
3927 onSpeechStart : ( ) => {
40- if ( ! isProcessing ) {
28+ if ( ! isProcessingRef . current ) {
29+ const sttModel = editorContext ?. aiModelConfig . getSTTModel ( ) ;
30+ const llmModel = editorContext ?. aiModelConfig . getLLMModel ( ) ;
31+ const ttsModel = editorContext ?. aiModelConfig . getTTSModel ( ) ;
32+ let isConfigured = true ;
33+ if ( ! sttModel ) {
34+ toast . error ( "STT model is not configured in settings." ) ;
35+ isConfigured = false ;
36+ }
37+ if ( ! llmModel ) {
38+ toast . error ( "LLM model is not configured in settings." ) ;
39+ isConfigured = false ;
40+ }
41+ if ( ! ttsModel ) {
42+ toast . error ( "TTS model is not configured in settings." ) ;
43+ isConfigured = false ;
44+ }
45+
46+ if ( ! isConfigured ) {
47+ return ;
48+ }
49+
4150 editorContext ?. setEditorStates ( ( prev ) => ( {
4251 ...prev ,
4352 isListening : true ,
4453 } ) ) ;
4554 }
4655 } ,
4756 onSpeechEnd : ( audio ) => {
48- if ( ! isProcessing ) {
49- setIsProcessing ( true ) ;
57+ if ( ! isProcessingRef . current ) {
58+ isProcessingRef . current = true ;
5059 const wavBuffer = utils . encodeWAV ( audio ) ;
5160 const blob = new Blob ( [ wavBuffer ] , { type : "audio/wav" } ) ;
5261 console . log ( "Speech end\n" , blob ) ;
5362
54- if ( ! llmModelRef . current ) {
55- toast . error ( "LLM model not loaded" ) ;
56- return ;
57- }
58- const agent = new CodeEditorAgent (
59- sttModelRef . current ,
60- llmModelRef . current ,
61- ttsModelRef . current ,
62- ) ;
63- const codeEditor = editorContext ?. getViewById ( "1" ) as CodeEditorViewRef ;
64- const viewDocument = codeEditor ?. getViewDocument ( ) ;
63+ const sttModel = editorContext ?. aiModelConfig . getSTTModel ( ) as BaseSTT ;
64+ const llmModel = editorContext ?. aiModelConfig . getLLMModel ( ) as BaseLLM ;
65+ const ttsModel = editorContext ?. aiModelConfig . getTTSModel ( ) as BaseTTS ;
66+
67+ const agent = new CodeEditorAgent ( sttModel , llmModel , ttsModel ) ;
68+ const activeView = editorContext ?. viewManager ?. getActiveView ( ) ;
69+ const viewDocument = activeView ?. viewDocument ;
6570 editorContext ?. setEditorStates ( ( prev ) => ( {
6671 ...prev ,
6772 isListening : false ,
@@ -83,9 +88,7 @@ export default function Home() {
8388 } ) ) ;
8489
8590 // Apply changes
86- const codeEditor = editorContext ?. getViewById (
87- "1" ,
88- ) as CodeEditorViewRef ;
91+ const codeEditor = activeView ?. viewRef as CodeEditorViewRef ;
8992 codeEditor ?. applyChanges ( changes ) ;
9093
9194 // Play the audio in the blob
@@ -97,7 +100,7 @@ export default function Home() {
97100 ...prev ,
98101 isSpeaking : false ,
99102 } ) ) ;
100- setIsProcessing ( false ) ;
103+ isProcessingRef . current = false ;
101104 } ;
102105 editorContext ?. setEditorStates ( ( prev ) => ( {
103106 ...prev ,
@@ -106,68 +109,12 @@ export default function Home() {
106109 audio . play ( ) ;
107110 return ;
108111 }
109- setIsProcessing ( false ) ;
112+ isProcessingRef . current = false ;
110113 } ) ;
111114 }
112115 } ,
113116 } ) ;
114117
115- // Load models
116- useEffect ( ( ) => {
117- if ( editorContext ?. persistSettings ) {
118- // Load STT
119- if (
120- editorContext ?. persistSettings . sttAPIKey &&
121- editorContext ?. persistSettings . sttProvider &&
122- editorContext ?. persistSettings . sttModel
123- ) {
124- const model = getModelSTT (
125- editorContext ?. persistSettings . sttAPIKey ,
126- editorContext ?. persistSettings . sttProvider ,
127- editorContext ?. persistSettings . sttModel ,
128- ) ;
129- sttModelRef . current = model ;
130- } else {
131- toast . error ( "Please set STT Provider, Model and API key in settings" ) ;
132- }
133-
134- // Load LLM
135- if (
136- editorContext ?. persistSettings . llmAPIKey &&
137- editorContext ?. persistSettings . llmProvider &&
138- editorContext ?. persistSettings . llmModel
139- ) {
140- const model = getModelLLM (
141- editorContext ?. persistSettings . llmAPIKey ,
142- editorContext ?. persistSettings . llmProvider ,
143- editorContext ?. persistSettings . llmModel ,
144- 0.85 ,
145- ) ;
146- llmModelRef . current = model ;
147- } else {
148- toast . error ( "Please set LLM Provider, Model and API key in settings" ) ;
149- }
150-
151- // Load TTS
152- if (
153- editorContext ?. persistSettings . ttsAPIKey &&
154- editorContext ?. persistSettings . ttsProvider &&
155- editorContext ?. persistSettings . ttsModel &&
156- editorContext ?. persistSettings . ttsVoice
157- ) {
158- const model = getModelTTS (
159- editorContext ?. persistSettings . ttsAPIKey ,
160- editorContext ?. persistSettings . ttsProvider ,
161- editorContext ?. persistSettings . ttsModel ,
162- editorContext ?. persistSettings . ttsVoice ,
163- ) ;
164- ttsModelRef . current = model ;
165- } else {
166- toast . error ( "Please set TTS Provider, Model and API key in settings" ) ;
167- }
168- }
169- } , [ editorContext ?. persistSettings ] ) ;
170-
171118 // Toggle recording
172119 useEffect ( ( ) => {
173120 if ( editorContext ?. editorStates ?. isRecording ) {
@@ -177,77 +124,10 @@ export default function Home() {
177124 }
178125 } , [ editorContext ?. editorStates , vad ] ) ;
179126
180- // useEffect(() => {
181- // const url = "/test.tsx";
182- // if (url) {
183- // fetch(url)
184- // .then((res) => res.text())
185- // .then((text) => {
186- // const viewId = "1";
187-
188- // // Init a new viewDocument
189- // const viewDocument: ViewDocument = {
190- // fileContent: text,
191- // filePath: url,
192- // };
193-
194- // // Get the code editor view
195- // const codeEditor = editorContext?.getViewById(
196- // viewId,
197- // ) as CodeEditorViewRef;
198-
199- // // Set the viewDocument
200- // codeEditor?.setViewDocument(viewDocument);
201- // });
202- // }
203- // }, []);
204-
205127 return (
206128 < div className = "flex h-full w-full flex-col" >
207129 < EditorToolbar />
208-
209- < div className = "flex h-full w-full flex-col p-1" >
210- < div className = "flex h-full w-full flex-col items-start justify-between space-y-1.5 overflow-hidden rounded-xl bg-default p-2" >
211- < div
212- className = { `min-h-0 w-full flex-grow` }
213- style = { {
214- cursor :
215- editorContext ?. editorStates ?. isDrawing && ! isCanvasReady
216- ? "wait"
217- : "auto" ,
218- } }
219- >
220- < CodeEditorView
221- ref = { ( ref ) => {
222- if ( ref ) editorContext ?. addView ( "1" , ref ) ;
223- } }
224- width = "100%"
225- height = "100%"
226- isDrawingMode = { editorContext ?. editorStates ?. isDrawing }
227- isDownloadClip = { editorContext ?. editorStates ?. isDownloadClip }
228- isDrawHulls = { editorContext ?. editorStates ?. isDrawHulls }
229- setIsCanvasReady = { setIsCanvasReady }
230- />
231- </ div >
232- < AnimatePresence >
233- { editorContext ?. editorStates ?. isOpenChatView && (
234- < motion . div
235- className = "h-full min-h-[60%] w-full pb-14"
236- // Enter from bottom and exit to bottom
237- initial = { { y : "100%" } }
238- animate = { { y : 0 } }
239- exit = { { y : "100%" } }
240- >
241- < AgentChatTerminalView
242- ref = { ( ref ) => {
243- if ( ref ) editorContext ?. addView ( "2" , ref ) ;
244- } }
245- />
246- </ motion . div >
247- ) }
248- </ AnimatePresence >
249- </ div >
250- </ div >
130+ < ViewDisplayArea />
251131 </ div >
252132 ) ;
253133}
0 commit comments