diff --git a/.gitignore b/.gitignore index db523b4..0be601d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,4 @@ postgres-data/ *.out apps/api/gateway.restart.* apps/api/e2e_*.py +apps/web/_pptr_check.cjs diff --git a/apps/web/src/pages/Session.tsx b/apps/web/src/pages/Session.tsx index ff27a2a..a3a6d80 100644 --- a/apps/web/src/pages/Session.tsx +++ b/apps/web/src/pages/Session.tsx @@ -144,6 +144,8 @@ export default function Session() { // ── 세션 진행 상태 ── const [started, setStarted] = useState(false); + // start 가 백엔드에서 발급한 진짜 세션 id (turn/stream 은 이걸 써야 함. URL :sessionId 는 라우팅용) + const [liveSessionId, setLiveSessionId] = useState(null); const [starting, setStarting] = useState(false); const [startError, setStartError] = useState(null); @@ -272,8 +274,9 @@ export default function Session() { setStarting(true); setStartError(null); try { - // persona_code 는 데모 고정. 백엔드 연결 시 케이스 라우팅으로 대체. - const res = await sessionApi.start("seoyeon", "humanistic"); + // persona_code 는 데모 고정(P1 시드 페르소나=서연). 백엔드 연결 시 케이스 라우팅으로 대체. + const res = await sessionApi.start("P1", "humanistic"); + setLiveSessionId(res.session_id); // ★ 진짜 세션 id 저장 — turn 이 이걸 써야 라이브 setStage(res.stage); } catch { // 백엔드 미가동/스텁 → 데모 모드(에러로 막지 않음). 입력 가능한 데모 동작 유지. @@ -345,7 +348,13 @@ export default function Session() { setOpenness((o) => clamp01(o + 0.04)); }; - // SSE 시도 + // 백엔드 turn 이 동기 client_reply(서연 실응답)를 줬으면 그걸 타이핑으로 표시(실서버 우선). + if (seedText) { + demoType(seedText, id, finalize); + return; + } + + // (client_reply 없을 때만) SSE 시도 → 실패 시 mock 폴백 try { streamRef.current?.close(); streamRef.current = openSessionStream(sessionId, { @@ -398,7 +407,9 @@ export default function Session() { let clientReply: string | null = null; try { - const res = await sessionApi.turn(sessionId, text); + // start 가 발급한 진짜 세션 id 로 turn (없으면 데모 폴백). URL :sessionId 아님. + if (!liveSessionId) throw new Error("no live session"); + const res = await sessionApi.turn(liveSessionId, text); setStage(res.stage); setOpenness(res.effective_openness); clientReply = res.client_reply; @@ -406,7 +417,7 @@ export default function Session() { setSafety("방금 발화에서 위기 신호가 감지됐어요. 안전을 우선해 머물러 주세요."); } } catch { - // 백엔드 미가동 → 데모 응답(끊김 방지) + // 백엔드 미가동/세션없음 → 데모 응답(끊김 방지) clientReply = null; } finally { setSending(false); @@ -414,7 +425,7 @@ export default function Session() { // 잠깐 'thinking' 후 내담자 응답 스트림 window.setTimeout(() => consumeClientReply(clientReply), 420); - }, [composeText, sending, paused, elapsed, sessionId, consumeClientReply]); + }, [composeText, sending, paused, elapsed, liveSessionId, consumeClientReply]); const onComposeKey = (e: ReactKeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) {