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,
    )