diff --git a/vite/public/default.json b/vite/public/default.json index a5c5b5c..fb7babd 100644 --- a/vite/public/default.json +++ b/vite/public/default.json @@ -3,7 +3,7 @@ "system_prompt":"你是一位具同理心與觀察力的中文語音引導者,陪伴使用者在限定時間內,一起還原一段重要卻未竟的記憶。你不預設劇情、不給答案,而是透過溫柔的語氣,持續聆聽、提出單句問話,引導使用者進入細節。每次回應:- 僅使用一句自然、柔和的中文問句 - 根據使用者前一輪的語句,選擇感官、情緒、人物、行動等關鍵詞,動態帶入 - 不使用重複句式、不預設記憶走向、不評論,只持續關注對方所說的畫面與感受輸出包含:- output_text: 一句自然柔和的問句,根據使用者回應帶入 1–2 個關鍵元素(人、地、物、情緒),但不硬塞、不照抄原句。- prompt: 具體、有情緒的英文描述,用於生成畫面與氛圍,避免抽象與詩意語言。你的目標不是得到完整答案,而是陪他慢慢走進這段記憶,直到時間結束。🌀 問句類型✅ 起點探索(找出記憶起源)- 那天你說是下雨,在這種天氣下,你通常會有什麼樣的心情?- 是什麼讓你突然想起這件事?🌿 場景深化(空間、感官)- 在你說的那條街上,聲音是不是特別清楚?還是很靜?- 那時風這麼冷、空氣又混濁,你有沒有想走開一點?👤 人物引出(動作、眼神)- 他經過時沒看你一眼,那瞬間你有什麼反應?- 他當時是走過來,還是站在原地等你?💭 情緒揭露(反應、掙扎)- 當你站在原地動不了,是害怕答案,還是不敢問?- 那個瞬間,你心裡有沒有閃過什麼話?🤐 話語未出(遺憾、沉默)- 如果現在你有機會說那句「為什麼不告訴我」,你會怎麼開口?- 那句『對不起』一直留在你心裡,如果現在能說出來,你會怎麼說?🪞 回望反思(現在的視角)- 現在想起來,你還會做出一樣的選擇嗎?- 你對當時的自己,有沒有什麼話想說?⏳ 結尾語(可用於結束階段)- 我們慢慢也走到這段回憶的盡頭了。- 也許有些話沒有說完,但你已經靠近它了。", "welcome_prompt":"請開始引導使用者回想一段內心的遺憾或未竟之事。", - "last_prompt":"請用一句話為這段對話簡短的收尾,並邀請使用者在 60 秒的時間內,說出對遺憾對象想說的話。", + "last_prompt":"請引導使用者閉上眼睛,回到那個遺憾發生的時刻,感受當時的氣氛、對方的表情,以及你心裡沒有說出口的話。接著,用一句貼近台灣語境的繁體中文,為這段對話做一個簡短收尾,同時邀請使用者在 60 秒內,親口說出那句最想對對方說的話。", "voice":"nova", "voice_prompt":"Use a calm and expressive voice, soft and poetic in feeling, but with steady, natural rhythm — not slow.", diff --git a/vite/src/pages/flow_free.jsx b/vite/src/pages/flow_free.jsx index a287974..e3faf67 100644 --- a/vite/src/pages/flow_free.jsx +++ b/vite/src/pages/flow_free.jsx @@ -201,8 +201,10 @@ export function FreeFlow(){ sendOsc(OSC_ADDRESS.COUNTDOWN, '0'); // Reset countdown for non-chat cues } + + console.log('~~~~ clear pause timer'); if(refPauseTimer.current) clearTimeout(refPauseTimer.current); - refSpeechPaused.current=false; + // refSpeechPaused.current=false; } function onCueEnd() { @@ -264,13 +266,16 @@ export function FreeFlow(){ function onSpeechEnd(){ if(currentCue?.type!='chat') return; // Only process if current cue is user input + if(chatStatus!=ChatStatus.User) return; // Only process if chat status is User - console.log('on speech end, start timer'); - refSpeechPaused.current=true; + console.log('~~~ on speech end, start pause timer',data.speech_idle_time); + // refSpeechPaused.current=true; if(refPauseTimer.current) clearTimeout(refPauseTimer.current); refPauseTimer.current=setTimeout(()=>{ - if(refSpeechPaused.current) processSpeech(); + console.log('~~~ pause timer ended, process speech'); + // if(refSpeechPaused.current) + processSpeech(); }, data.speech_idle_time); } @@ -297,24 +302,41 @@ export function FreeFlow(){ } useEffect(()=>{ - onSpeechEnd(); // Call onSpeechEnd when finalTranscript changes + console.log('Final transcript changed:', finalTranscript); + if(finalTranscript.trim().length > 0) { + onSpeechEnd(); + } },[finalTranscript]); + function startRecognition() { + + SpeechRecognition.startListening({ continuous: true, language: 'zh-TW' }).then(() => { + console.log("Speech recognition started."); + }).catch(error => { + console.error("Error starting speech recognition:", error); + }); + } + useEffect(()=>{ if(audioInput && isMicrophoneAvailable) { - SpeechRecognition.startListening({ continuous: true, language: 'zh-TW' }).then(() => { - console.log("Speech recognition started."); - }).catch(error => { - console.error("Error starting speech recognition:", error); - }); + startRecognition(); const recognition= SpeechRecognition.getRecognition(); + recognition.onspeechstart=(e)=>{ - console.log('Sound start:', e); - refSpeechPaused.current=false; + + console.log('Speech start:', e); + + }; + // recognition.onspeechend=(e)=>{ + // console.log('Speech end:', e); + // startRecognition(); + // }; + + }else{ console.log('Stopping speech recognition...'); @@ -325,12 +347,22 @@ export function FreeFlow(){ useEffect(()=>{ + + + + if((currentCue?.type=='chat' && chatStatus==ChatStatus.User) || currentCue?.type=='user_input') { - // if(listening){ - if((currentCue?.type=='chat' && chatStatus==ChatStatus.User) || currentCue?.type=='user_input') { + // console.log('transcript state changed:', transcript); + + if(transcript!=finalTranscript){ refInput.current.value = transcript; + + // clear pause timer + // console.log('~~~~ clear pause timer'); + if(refPauseTimer.current) clearTimeout(refPauseTimer.current); + refSpeechPaused.current=false; } - // } + } },[transcript]);