File size: 1,804 Bytes
c857b85 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | """
Stage 3 오케스트레이터 — 캐릭터 반응 + 정원 + 리캡 생성
입력: Stage 2 출력 (Stage2Output)
출력: Stage 3 출력 (Stage3Output)
"""
from src.common.schemas import Stage2Output, Stage3Output, Segment
from src.stage3.character_mapping import map_characters
from src.stage3.garden_logic import compute_garden_update
from src.stage3.recap_generator import generate_recap_llm, generate_recap_fallback
def process(
stage2_output: Stage2Output,
segments: list[Segment] | None = None,
current_garden_level: int = 1,
use_llm: bool = True,
) -> Stage3Output:
"""
Stage 3 메인 진입점.
Args:
stage2_output: Stage 2의 감정 분석 결과
segments: Stage 1의 발화 세그먼트 (리캡 생성에 사용, 없으면 fallback)
current_garden_level: 현재 정원 레벨 (DB에서 가져옴)
use_llm: True면 Claude API 리캡, False면 규칙 기반 fallback
"""
# 1. 캐릭터 반응 매핑
character_reactions = map_characters(stage2_output.speaker_summaries)
# 2. 정원 성장 계산
garden_update = compute_garden_update(
stage2_output.speaker_summaries,
current_level=current_garden_level,
)
# 3. 리캡 생성
if use_llm and segments:
recap_card = generate_recap_llm(segments, stage2_output.speaker_summaries)
else:
recap_card = generate_recap_fallback(stage2_output.speaker_summaries)
return Stage3Output(
call_id=stage2_output.call_id,
character_reactions=character_reactions,
garden_update=garden_update,
recap_card=recap_card,
# Surface Stage2 data at top level for frontend convenience
emotions=stage2_output.emotions,
speaker_summaries=stage2_output.speaker_summaries,
)
|