| """ |
| 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 |
| """ |
| |
| character_reactions = map_characters(stage2_output.speaker_summaries) |
|
|
| |
| garden_update = compute_garden_update( |
| stage2_output.speaker_summaries, |
| current_level=current_garden_level, |
| ) |
|
|
| |
| 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, |
| |
| emotions=stage2_output.emotions, |
| speaker_summaries=stage2_output.speaker_summaries, |
| ) |
|
|