coconut / src /pipeline /models.py
alohaboy
feat: Add LLM-based chat mode and integrate YJ pipeline
caf53ab
# YJ/pipeline/models.py
from __future__ import annotations
from typing import List, Optional, Literal, Dict, Any
from uuid import uuid4
from pydantic import BaseModel, Field
class LanguageAssessment(BaseModel):
tool: Optional[str] = None # REVT, SELSI 등
result_level: Optional[str] = None # e.g. "mild_delay", "within_range"
notes: Optional[str] = None
class DevelopmentHistory(BaseModel):
preterm: Optional[bool] = None
diagnosed_conditions: List[str] = Field(default_factory=list)
hearing_issues: Optional[bool] = None
class LanguageEnvironment(BaseModel):
languages_exposed: List[str] = Field(default_factory=lambda: ["Korean"])
caregivers: Optional[int] = None
caregiver_speech_style: Optional[str] = None # e.g. "many_directives_few_questions"
class BaselineCommunication(BaseModel):
echolalia_frequency: Optional[str] = None # "rare", "sometimes", "often"
spontaneous_utterance_level: Optional[str] = None # "single_words", "two_words", ...
scripted_phrases_present: Optional[bool] = None
class UserProfile(BaseModel):
user_id: str
child_nickname: Optional[str] = None
age_months: Optional[int] = None
sex: Optional[Literal["male", "female", "unspecified"]] = "unspecified"
language_assessment: Optional[LanguageAssessment] = None
development_history: Optional[DevelopmentHistory] = None
language_environment: Optional[LanguageEnvironment] = None
baseline_communication: Optional[BaselineCommunication] = None
class DialogueTurn(BaseModel):
speaker: Literal["caregiver", "child", "other"]
utterance: str
turn_index: int
class UtteranceAnalysisRequest(BaseModel):
user_id: str
context_description: str
dialogue_log: List[Dict[str, str]] # raw 입력 (speaker, utterance)
timestamp: Optional[str] = None
# --- 중간 단계 출력 모델들 ---
class EcholaliaDetectionResult(BaseModel):
is_echolalia: bool
type: Optional[Literal["immediate", "delayed", "mixed", "uncertain"]] = None
completeness: Optional[Literal["full", "partial", "transformed"]] = None
functional: Optional[bool] = None
evidence: Optional[str] = None
class EcholaliaFunction(BaseModel):
tag: Literal[
"FILLING_TURN",
"SAYING_YES",
"LABELING_PRACTICE",
"SELF_SOOTHING_ROUTINE",
"STIMMING_VERBAL",
"SOUND_PLEASURE",
"LANGUAGE_PROCESSING_OUTLOUD",
"SITUATION_SCRIPT_REPLAY",
"COMMUNICATION_ATTEMPT",
"ANXIETY_DEFENSE",
]
confidence: float
caregiver_explanation: str
class MeaningInferenceResult(BaseModel):
echolalia_functions: List[EcholaliaFunction]
primary_interpretation: str
class DomainProfile(BaseModel):
summary: str
relative_level: Literal[
"strength",
"age_appropriate",
"age_appropriate_or_mild_delay",
"developing",
"emerging",
"needs_more_observation",
]
notes: Optional[str] = None
class DevelopmentProfile(BaseModel):
age_reference: Optional[int] = None
domains: Dict[str, DomainProfile]
safety_note: str
class ParentGuide(BaseModel):
summary_line: str
immediate_response: List[str]
modeling_utterance: List[str]
long_term_tips: List[str]
class SafetyFlags(BaseModel):
contains_diagnostic_language: bool
needs_professional_referral_suggestion: bool
sanitized_text: Optional[Dict[str, Any]] = None # 수정된 parent_guide 등
class UtteranceAnalysisResult(BaseModel):
meta: Dict[str, Any]
echolalia_detection: EcholaliaDetectionResult
meaning_inference: MeaningInferenceResult
development_profile: DevelopmentProfile
parent_guide: ParentGuide
safety_flags: SafetyFlags
@staticmethod
def new_meta(user_id: str, model_version: str = "coconut-v0.1") -> Dict[str, Any]:
return {
"user_id": user_id,
"analysis_id": str(uuid4()),
"model_version": model_version,
}