# echolalia_assistant/src/pipeline/text_processor.py """ gradio_app.py의 process_text 함수를 위한 래퍼 새로운 3단계 Phase 파이프라인을 사용하여 기존 인터페이스와 호환 """ from __future__ import annotations from typing import Tuple, Optional from .coconut_pipeline import run_full_analysis from .models import UtteranceAnalysisRequest def process_text_with_pipeline( text: str, context_situation: str, situation: str = "기타", profile_id: Optional[int] = None, analysis_mode: str = "detailed" ) -> Tuple[bool, str, str, str, str, str, str]: """ 새로운 3단계 Phase 파이프라인을 사용하여 텍스트 분석 Returns: (is_echo, confidence_html, quick_summary_text, three_step_text, detailed_report, save_message, analysis_id) analysis_id는 Optional[int]이지만 Tuple에서는 None을 반환 """ # UtteranceAnalysisRequest 생성 user_id = str(profile_id) if profile_id else "anonymous" # 대화 로그 구성 (간단한 형태) dialogue_log = [ {"speaker": "caregiver", "utterance": context_situation or "상황 설명 없음"}, {"speaker": "child", "utterance": text} ] req = UtteranceAnalysisRequest( user_id=user_id, context_description=context_situation or situation, dialogue_log=dialogue_log, ) # 파이프라인 실행 try: result = run_full_analysis(req) # 결과 파싱 is_echo = result.echolalia_detection.is_echolalia # 신뢰도 계산 (반향어 감지 결과 기반) # YJ 파이프라인 결과를 기반으로 더 세밀한 신뢰도 계산 if is_echo: # 반향어가 탐지된 경우 # type, completeness, functional을 종합적으로 고려 type_weight = { 'immediate': 0.9, # 즉각적 반향어는 높은 신뢰도 'delayed': 0.7, # 지연 반향어는 중간 신뢰도 'mixed': 0.6, # 혼합은 낮은 신뢰도 'uncertain': 0.4 # 불확실은 더 낮은 신뢰도 } completeness_weight = { 'full': 1.0, 'partial': 0.7, 'transformed': 0.5 } # 기본 신뢰도 (type 기반) base_confidence = type_weight.get(result.echolalia_detection.type, 0.5) # completeness 조정 completeness_mult = completeness_weight.get(result.echolalia_detection.completeness, 0.7) # functional 여부 조정 functional_bonus = 0.1 if result.echolalia_detection.functional else 0.0 # 최종 신뢰도 계산 (0.3 ~ 0.9 범위) confidence = min(0.9, max(0.3, base_confidence * completeness_mult + functional_bonus)) else: # 반향어가 아닌 경우 낮은 신뢰도 confidence = 0.2 # 기존 형식으로 변환 confidence_html = _generate_confidence_html(is_echo, confidence * 100) quick_summary_text = _generate_quick_summary(result, text) three_step_text = "" # 3단계 변환 제안 제거 detailed_report = _generate_detailed_report( result, analysis_mode, text, context_situation, situation, profile_id, None ) save_message = "분석 결과가 프로필에 저장되었습니다." if profile_id else "프로필을 선택하면 분석 결과가 자동으로 저장됩니다." analysis_id = None # TODO: DB에 저장하고 ID 반환 return (is_echo, confidence_html, quick_summary_text, three_step_text, detailed_report, save_message, analysis_id) except Exception as e: # 오류 발생 시 기본값 반환 import traceback error_trace = traceback.format_exc() print(f"❌ process_text_with_pipeline 에러: {e}") print(f"에러 상세:\n{error_trace}") error_html = f"

❌ 분석 오류

{str(e)}

" return (False, error_html, "", "", "", f"분석 중 오류가 발생했습니다: {str(e)}", None) # 7개 반환값 def _generate_confidence_html(is_echo: bool, confidence: float) -> str: """신뢰도 HTML 생성""" if confidence >= 70: color = "#ef4444" bg_color = "#fee2e2" icon = "⚠️" urgency = "관찰 필요" elif confidence >= 40: color = "#f59e0b" bg_color = "#fef3c7" icon = "📊" urgency = "지속 관찰" else: color = "#10b981" bg_color = "#d1fae5" icon = "✅" urgency = "양호" return f"""
{icon}

{confidence:.0f}%

{urgency}

""" def _generate_quick_summary(result, text: str) -> str: """빠른 요약 생성""" is_echo = result.echolalia_detection.is_echolalia primary_interpretation = result.meaning_inference.primary_interpretation if is_echo: return f""" ### ⚠️ 분석 결과 요약 **아이의 말**: "{text}" {primary_interpretation} """ else: return f""" ### ✅ 분석 결과 요약 **아이의 말**: "{text}" 정상적인 의사소통 패턴으로 보입니다. 🎉 """ def _translate_echolalia_tag(tag: str) -> str: """반향어 기능 태그를 한국어로 변환""" tag_map = { "FILLING_TURN": "대화 차례 채우기", "SAYING_YES": "동의 표현", "LABELING_PRACTICE": "명명 연습", "SELF_SOOTHING_ROUTINE": "자기 진정 루틴", "STIMMING_VERBAL": "구어적 자극 행동", "SOUND_PLEASURE": "소리 즐기기", "LANGUAGE_PROCESSING_OUTLOUD": "언어 처리 발화", "SITUATION_SCRIPT_REPLAY": "상황 스크립트 재현", "COMMUNICATION_ATTEMPT": "의사소통 시도", "ANXIETY_DEFENSE": "불안 방어", } return tag_map.get(tag, tag) def _translate_relative_level(level: str) -> str: """발달 수준을 한국어로 변환""" level_map = { "strength": "강점 영역", "age_appropriate": "또래 수준", "age_appropriate_or_mild_delay": "또래 수준 (약간의 지연 가능)", "developing": "발달 진행 중", "emerging": "발달 시작 단계", "needs_more_observation": "추가 관찰 필요", } return level_map.get(level, level) def _generate_detailed_report(result, analysis_mode: str, text: str = "", context_situation: str = "", situation: str = "기타", profile_id: int = None, analysis_id: int = None) -> str: """ 상세 보고서 생성 - 새로운 파이프라인 결과만 사용하여 "아이의 말에 담긴 마음" 형식으로 생성 """ if analysis_mode == "quick": return "" # 새로운 파이프라인 결과를 기반으로 "아이의 말에 담긴 마음" 형식의 보고서 생성 is_echo = result.echolalia_detection.is_echolalia # 1️⃣ 아이의 언어 성향 분석 (Personal Profile) - 파이프라인 결과 기반 profile_info = "" if result.development_profile.age_reference: age_years = result.development_profile.age_reference // 12 age_months = result.development_profile.age_reference % 12 profile_info = f""" **👶 기본 정보** - **나이**: {age_years}세 {age_months}개월 - **반향어 경향**: {'높은 경향' if is_echo else '낮은 경향'} ({result.echolalia_detection.type or '미확인'}) """ # 반향어 유형 및 기능 분석 echo_type_kr = { 'immediate': '즉시 반향어', 'delayed': '지연 반향어', 'mixed': '혼합형', 'uncertain': '불확실' }.get(result.echolalia_detection.type, '미확인') primary_function = "" if result.meaning_inference.echolalia_functions: top_function = result.meaning_inference.echolalia_functions[0] function_tag_kr = _translate_echolalia_tag(top_function.tag) primary_function = f""" **🧠 언어 지도 (Language Map)** 아이는 **{echo_type_kr}**를 주로 사용하며, 반복 언어를 통해 **{function_tag_kr}** 기능을 하고 있습니다. {top_function.caregiver_explanation} **💡 언어 특성 이해** - **사회적 상호작용**: {echo_type_kr}를 통한 의사소통 시도 - **언어적 유연성**: 반복을 통한 안정감 추구 - **감정 표현**: 반복 언어를 통한 내적 상태 전달 """ personal_profile = f""" ### 1️⃣ 아이의 언어 성향 분석 (Personal Profile) {profile_info} {primary_function} """ # 2️⃣ 입력 발화 및 대화 분석 (Context & Function) - 파이프라인 결과 기반 context_interpretation = "" if result.echolalia_detection.evidence: if result.echolalia_detection.functional: context_interpretation = "**상황과 잘 맞는 발화**입니다. 아이가 현재 상황을 이해하고 적절하게 반응하고 있습니다." else: context_interpretation = "**부분적으로 상황과 연관된 발화**입니다. 아이가 상황의 일부를 이해하고 있지만 완전한 연결은 어려워 보입니다." else: context_interpretation = "**상황과 무관한 발화**일 가능성이 높습니다. 아이가 이전에 들은 말을 현재 상황과 연결하지 못하고 있습니다." function_type = "**의미 전달**" if result.echolalia_detection.functional else "**단순 모방**" function_desc = "아이가 명확한 의미를 전달하려고 시도하고 있습니다." if result.echolalia_detection.functional else "아이가 이전에 들은 말을 그대로 반복하고 있습니다." context_function_analysis = f""" ### 2️⃣ 입력 발화 및 대화 분석 (Context & Function) **🗣️ 발화 내용**: "{text}" **📍 맥락 분석** - **상황**: {situation} - **상황 설명**: {context_situation if context_situation else '제공되지 않음'} {context_interpretation} **🔍 기능 분석** - **발화 유형**: {function_type} - **설명**: {function_desc} **💭 구체적 해석** {result.meaning_inference.primary_interpretation} **반향어 기능 분석**: """ for func in result.meaning_inference.echolalia_functions: function_tag_kr = _translate_echolalia_tag(func.tag) context_function_analysis += f"- **{function_tag_kr}** (신뢰도: {func.confidence:.1%}): {func.caregiver_explanation}\n" # 3️⃣ 보완 방향 (Alternative & Strategy) - 파이프라인 결과 기반 caregiver_response = f""" **🧡 보호자 반응 방식** ✅ **해야 할 것** """ for response in result.parent_guide.immediate_response: caregiver_response += f"- {response}\n" caregiver_response += f""" **💬 아이를 위한 대안 발화 모델링** """ for utterance in result.parent_guide.modeling_utterance: caregiver_response += f"- {utterance}\n" caregiver_response += f""" **🎯 장기 지원 팁** """ for tip in result.parent_guide.long_term_tips: caregiver_response += f"- {tip}\n" alternative_strategy = f""" ### 3️⃣ 보완 방향 (Alternative & Strategy) {caregiver_response} **📚 발달 영역별 평가 및 지원 방향** """ for domain, domain_profile in result.development_profile.domains.items(): domain_name_kr = { 'pragmatics': '화용론', 'semantics': '의미론', 'morphosyntax': '형태통사론', 'communicative_function': '의사소통 기능' }.get(domain, domain) level_kr = _translate_relative_level(domain_profile.relative_level) alternative_strategy += f""" **{domain_name_kr}** - **수준**: {level_kr} - **요약**: {domain_profile.summary} - **참고사항**: {domain_profile.notes or '없음'} """ if result.development_profile.safety_note: alternative_strategy += f"\n**안전 참고사항**: {result.development_profile.safety_note}\n" # 최종 보고서 조립 report = f"""## 🌟 아이의 말에 담긴 마음 - 3단계 분석 보고서 **📌 참고사항**: 이 보고서는 coconut AI가 의학 자문을 통해 검증한 고유 데이터베이스를 기반으로 생성되었습니다. {personal_profile} {context_function_analysis} {alternative_strategy} --- *이 보고서는 공감적 접근을 바탕으로 한 AI 분석 시스템을 통해 생성되었습니다. 정확한 진단을 위해서는 전문가와의 상담을 권장합니다.*""" return report