Jev 내담자 평가·표현 v2와 속마음 공개

상담자 발화 판정(A)·감정(B)·표현(C) 20문항 질문 세트, 감쇠 없는 이번 턴 반응과 비대칭 기분 전이, 개방도 게이트로 생성 지시를 만들고 ccd.coping_strategy 전달 누락을 고친다.

trace v2와 고정 문구 속마음 요약(migration 24, AI 경로 차단 RLS)을 같은 트랜잭션에 저장하고 피드백 정책이 켜진 경우에만 done·TurnResponse·음성 reply·리뷰로 노출한다. 회기 화면 속마음 보기 토글, 리뷰 접힘 블록, 관리자 감정 관측 v2 표시를 추가한다.
This commit is contained in:
Yun Chan 2026-09-30 13:23:09 +09:00
parent 36cb847e38
commit 29c406d89f
39 changed files with 5726 additions and 343 deletions

View file

@ -16,6 +16,7 @@ from typing import Any, Callable, Literal, Optional, cast
from pydantic import BaseModel, Field
from .config import settings
from .contracts.client_affect import ClientInnerReactionV1
from .services import guardrail, session_metrics, state_machine
from .stage_contract import (
ReviewPhaseKey,
@ -353,6 +354,8 @@ class ReviewTurn(BaseModel):
techniques: list[ReviewTechnique] = Field(default_factory=list)
nonverbal: list[ReviewNonverbalEvent] = Field(default_factory=list)
note: Optional[ReviewNote] = None
# 내담자 턴에만 채워지는 속마음 요약(§8.2·§9). feedback_hidden이면 넣지 않는다.
innerReaction: Optional[ClientInnerReactionV1] = None
class ReviewPhaseSegment(BaseModel):
@ -583,6 +586,7 @@ class SessionReviewReadInput:
teacher_review_record: dict[str, object] | None = None
learner_feedback_enabled: bool = True
expose_learner_feedback: bool = True
inner_reactions: dict[str, ClientInnerReactionV1] | None = None
now_ts: float | None = None
@ -2042,6 +2046,11 @@ def build_session_review(read_input: SessionReviewReadInput) -> SessionReviewRes
synthetic_generated=speaker == "client",
).text_masked
turn_eval = turn.evaluation if (speaker == "learner" and not feedback_hidden) else None
inner_reaction = (
(read_input.inner_reactions or {}).get(turn.turn_id)
if speaker == "client" and turn.turn_id and not feedback_hidden
else None
)
turns.append(
ReviewTurn(
id=f"t{index + 1}",
@ -2057,6 +2066,7 @@ def build_session_review(read_input: SessionReviewReadInput) -> SessionReviewRes
else []
),
note=_review_note_from_turn_eval(turn_eval, safe_turn_text),
innerReaction=inner_reaction,
)
)