
    Si                        U d Z ddlmZ ddlmZ dZded<   dZded<   d	Zded
<   dZ	ded<   dZ
ded<    eh d      Zded<   dZded<   dZded<   dZded<   ddZddZdd dZy)!u  스마트 모델 라우팅 유틸리티 (M-03).

작업 텍스트의 길이와 복잡도 키워드를 분석하여 적합한 Claude 모델을 선택한다.

- 단순 질문 (짧고 복잡 키워드 없음) → haiku
- 중간 길이 (복잡 키워드 없음)      → sonnet
- 복잡 키워드 포함                  → opus

config_loader에서 모델명 오버라이드를 읽을 수 있으며, 없으면 기본 상수를 사용한다.

Usage:
    from utils.model_router import route_model

    model = route_model("What is the weather?")           # → haiku
    model = route_model("Analyze and refactor this code") # → opus
    model = route_model("Explain this paragraph in detail") # → opus
    )annotations)Anyzclaude-haiku-4-5-20251001strMODEL_HAIKUzclaude-sonnet-4-6MODEL_SONNETzclaude-opus-4-6
MODEL_OPUS   int_MAX_SIMPLE_CHARS   _MAX_SIMPLE_WORDS>   debugdesignreviewanalyzecompareexplainmigratediagnoseoptimizerefactorsecurity	implement	integrateorchestrateperformancescalabilityarchitecturezfrozenset[str]_COMPLEX_KEYWORDSzmodels.router.haiku_CFG_KEY_HAIKUzmodels.router.sonnet_CFG_KEY_SONNETzmodels.router.opus_CFG_KEY_OPUSc                4   | t         t        t        fS | j                  t        t               xs t         }| j                  t
        t              xs t        }| j                  t        t              xs t        }t        |      t        |      t        |      fS )u   cfg에서 모델명을 읽어 (haiku, sonnet, opus) 튜플을 반환한다.

    cfg가 None이거나 키가 없으면 기본 상수를 사용한다.
    )r   r   r   getr    r!   r"   r   )cfghaikusonnetopuss       C/home/jay/workspace/.worktrees/task-2117-dev1/utils/model_router.py_resolve_modelsr*   E   sn    
 {L*44GGNK0?KEWW_l3C|F77=*-;Du:s6{CI--    c                h    | j                         }|D ]  }|j                  d      }|t        v s y y)uO   작업 텍스트(소문자)에 복잡 키워드가 포함되어 있으면 True.z
.,!?;:"'()TF)splitstripr   )
task_lowerwordswordcleans       r)   _has_complex_keywordr3   S   s>    E 

=)%%	
 r+   Nc                    t        |      \  }}}| j                         }t        |      r|S t        |       }t        | j	                               }|t
        k  r|t        k  r|S |S )u  작업 텍스트를 분석하여 최적 Claude 모델명을 반환한다.

    판단 순서:
    1. 복잡 키워드 포함 → opus
    2. 길이 ≤ 160자 AND 단어 수 ≤ 28 → haiku
    3. 그 외 → sonnet

    Args:
        task: 라우팅할 작업 텍스트.
        cfg:  Config 인스턴스 (config_loader.Config). None이면 기본 상수 사용.

    Returns:
        선택된 모델명 문자열.
    )r*   lowerr3   lenr-   r   r   )taskr%   haiku_modelsonnet_model
opus_modelr/   
char_count
word_counts           r)   route_modelr=   ^   sh     -<C,@)KzJ J' TJTZZ\"J&&:9J+Jr+   )r%   r   returnztuple[str, str, str])r/   r   r>   bool)N)r7   r   r%   r   r>   r   )__doc__
__future__r   typingr   r   __annotations__r   r   r   r   	frozensetr   r    r!   r"   r*   r3   r=    r+   r)   <module>rF      s   $ # 
 /S .'c '#
C #
  3  3 
 %.% > 2 , +- -)s ).r+   