update flow

main
reng 5 months ago
parent 0ab8acce8e
commit 6d2efc79c0
  1. 2
      vite/public/default.json
  2. 54
      vite/src/pages/flow_free.jsx

@ -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.",

@ -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]);
useEffect(()=>{
if(audioInput && isMicrophoneAvailable) {
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) {
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...');
@ -326,11 +348,21 @@ export function FreeFlow(){
useEffect(()=>{
// 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]);

Loading…
Cancel
Save