
    Mi/                     F   d Z ddlZddlmc mZ ddlZddlZddl	m
Z
 ddlZej                  j                  d e e
e      j                   j                   j                                ddlmZmZ  G d d      Z G d d      Z G d	 d
      Z G d d      Z G d d      Zy)uV   utils/aux_llm_router.py 테스트 스위트

TDD: 테스트 먼저 작성 후 구현.
    N)Path)	AuxRouterProviderConfigc                   0    e Zd ZdZddZddZddZddZy)TestProviderConfigu"   ProviderConfig dataclass 테스트Nc                    t        ddd      }|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}x}}|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}x}}|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}x}}y)u   필수 필드 생성 확인	anthropiczclaude-haiku-4-5ANTHROPIC_API_KEYnamemodelapi_key_env==z,%(py2)s
{%(py2)s = %(py0)s.name
} == %(py5)scfgpy0py2py5assert %(py7)spy7N)z-%(py2)s
{%(py2)s = %(py0)s.model
} == %(py5)s)z3%(py2)s
{%(py2)s = %(py0)s.api_key_env
} == %(py5)s)r   r   
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationr   r   selfr   @py_assert1@py_assert4@py_assert3@py_format6@py_format8s          6/home/jay/workspace/utils/tests/test_aux_llm_router.pytest_required_fieldsz'TestProviderConfig.test_required_fields   sf   $+

 xx&;&x;&&&&x;&&&&&&s&&&s&&&x&&&;&&&&&&&yy...y.....y.......s...s...y...........5"55"55555"5555555s555s555555"55555555    c                 >   t        ddd      }|j                  }d}||u }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}}|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      d	z  }d
d|iz  }t        t        j                  |            dx}x}}y)u#   base_url, priority 기본값 확인openaizgpt-4o-miniOPENAI_API_KEYr   Nis)z0%(py2)s
{%(py2)s = %(py0)s.base_url
} is %(py5)sr   r   r   r   r   r   z0%(py2)s
{%(py2)s = %(py0)s.priority
} == %(py5)sr   base_urlr   r   r   r   r   r   r   r    priorityr!   s          r(   test_optional_defaultsz)TestProviderConfig.test_optional_defaults%   s    (

 ||#t#|t####|t######s###s###|###t#######|| q |q    |q      s   s   |   q       r*   c                 D   t        ddddd      }|j                  }d}||k(  }|st        j                  d|fd||f      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            dx}x}}|j                  }d}||k(  }|st        j                  d|fd||f      d	t	        j
                         v st        j                  |      rt        j                  |      nd	t        j                  |      t        j                  |      d
z  }dd|iz  }t        t        j                  |            dx}x}}y)u#   base_url, priority 커스텀 설정deepseekzdeepseek-chatDEEPSEEK_API_KEYzhttps://api.deepseek.com/v1   )r   r   r   r2   r3   r   )z0%(py2)s
{%(py2)s = %(py0)s.base_url
} == %(py5)sr   r   r   r   Nr0   r1   r!   s          r(   !test_custom_base_url_and_priorityz4TestProviderConfig.test_custom_base_url_and_priority/   s    !*2
 ||<<<|<<<<<|<<<<<<<s<<<s<<<|<<<<<<<<<<<|| q |q    |q      s   s   |   q       r*   c                    t        ddd      }|j                  }d}||k(  }|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}x}}y)uL   dataclass 기본 동작 확인 (frozen 여부와 무관하게 생성 가능)googlezgemini-2.5-flashGOOGLE_API_KEYr   r   r   r   r   r   r   N)
r   r   r   r   r   r   r   r   r   r    r!   s          r(   2test_dataclass_is_mutable_or_frozen_does_not_crashzETestProviderConfig.test_dataclass_is_mutable_or_frozen_does_not_crash;   s    $(

 xx#8#x8####x8######s###s###x###8#######r*   returnN)__name__
__module____qualname____doc__r)   r4   r9   r=    r*   r(   r   r      s    ,	6!
!$r*   r   c                   (    e Zd ZdZddZddZddZy)TestAuxRouterInitu   AuxRouter 초기화 테스트Nc                    t               }|j                  D cg c]  }|j                   }}d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d	}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d
}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d}||v }|st        j                  d|fd||f      t        j
                  |      dt        j                         v st        j                  |      rt        j
                  |      nddz  }dd|iz  }t        t        j                  |            dx}}yc c}w )uD   기본 프로바이더 4개(anthropic/openai/google/deepseek) 등록r	   inz%(py1)s in %(py3)snamespy1py3assert %(py5)sr   Nr,   r;   r6   )r   	providersr   r   r   r   r   r   r   r   r    )r"   routerprK   @py_assert0@py_assert2@py_format4r&   s           r(   test_default_providers_loadedz/TestAuxRouterInit.test_default_providers_loadedM   s   !'!1!12A22#{e####{e###{######e###e####### x5    x5   x      5   5        x5    x5   x      5   5       "zU""""zU"""z""""""U"""U"""""""	 3s   Kc                    t        ddd      g}t        |      }|j                  }t        |      }d}||k(  }|s
t	        j
                  d|fd||f      d	t        j                         v st	        j                  t              rt	        j                  t              nd	d
t        j                         v st	        j                  |      rt	        j                  |      nd
t	        j                  |      t	        j                  |      t	        j                  |      dz  }dd|iz  }t        t	        j                  |            dx}x}x}}|j                  d   }	|	j                  }d}
||
k(  }|st	        j
                  d|fd||
f      t	        j                  |	      t	        j                  |      t	        j                  |
      dz  }dd|iz  }t        t	        j                  |            dx}	x}x}}
y)u'   커스텀 프로바이더 목록 주입zmy-providerzmy-modelMY_KEYr   rP      r   )zO%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.providers
})
} == %(py8)slenrQ   r   rM   rN   r   py8assert %(py10)spy10Nr   z,%(py3)s
{%(py3)s = %(py1)s.name
} == %(py6)srM   rN   py6assert %(py8)sr]   )r   r   rP   r[   r   r   r   r   r   r   r   r    r   )r"   customrQ   rT   r$   @py_assert7@py_assert6@py_format9@py_format11rS   @py_assert5@py_format7s               r(   test_custom_providersz'TestAuxRouterInit.test_custom_providersV   s;    ZXV
 V,##)s#$))$))))$))))))s)))s))))))6)))6)))#)))$))))))))))"8"''8=8'=8888'=888"888'888=8888888r*   c                    t        d      }|j                  }t        |      }d}||k\  }|s
t        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}x}x}}y)u2   providers=None이면 기본 프로바이더 사용NrY      )>=)zO%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.providers
})
} >= %(py8)sr[   rQ   r\   r^   r_   )r   rP   r[   r   r   r   r   r   r   r   r    )r"   rQ   rT   r$   re   rf   rg   rh   s           r(   !test_providers_none_uses_defaultsz3TestAuxRouterInit.test_providers_none_uses_defaults_   s    T*##)s#$))$))))$))))))s)))s))))))6)))6)))#)))$))))))))))r*   r>   )r@   rA   rB   rC   rV   rk   ro   rD   r*   r(   rF   rF   J   s    '#9*r*   rF   c                   0    e Zd ZdZddZddZddZddZy)TestGetAvailableProvidersu#   get_available_providers() 테스트Nc                 "   |j                  dd       |j                  dd       t        ddd      t        d	d
d      g}t        |      }|j	                         }t        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t
              rt        j                  t
              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|d   }
|
j                  }d}||k(  }|st        j                  d|fd||f      t        j                  |
      t        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}
x}x}}y)u;   API 키가 환경변수에 있는 프로바이더만 반환MY_KEY_Az	sk-test-aMY_KEY_BFraisingzhas-keym1r   zno-keym2rY   rZ   r   z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr[   	availabler   rM   rN   rb   rc   r]   Nr   r`   ra   )setenvdelenvr   r   get_available_providersr[   r   r   r   r   r   r   r   r    r   )r"   monkeypatchrP   rQ   rz   rT   ri   r$   rj   rg   rS   s              r(   (test_returns_only_providers_with_api_keyzBTestGetAvailableProviders.test_returns_only_providers_with_api_keym   sS   :{3:u5 	:N*M
	 Y/224	9~""~""""~""""""s"""s""""""9"""9"""~""""""""""|-|  -I- I---- I---|--- ---I-------r*   c                 j   |j                  dd       |j                  dd       t        ddd      t        dd	d      g}t        |
      }|j                  } |       }g }||k(  }|st	        j
                  d|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      t	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            dx}x}x}}y)u&   모든 키 미설정 시 빈 리스트MY_KEY_XFru   MY_KEY_Yp1rw   r   p2rx   rY   r   )zV%(py4)s
{%(py4)s = %(py2)s
{%(py2)s = %(py0)s.get_available_providers
}()
} == %(py7)srQ   )r   r   py4r   zassert %(py9)spy9N)r}   r   r   r~   r   r   r   r   r   r   r   r    )
r"   r   rP   rQ   r#   r%   rf   ri   r'   @py_format10s
             r(   test_empty_when_no_keys_setz5TestGetAvailableProviders.test_empty_when_no_keys_set|   s    :u5:u5 DjIDjI
	 Y/--5-/525/25555/2555555v555v555-555/55525555555r*   c                    |j                  dd       t        ddd      g}t        |      }|j                         }t	        |t
              }|sddt        j                         v st        j                  t              rt        j                  t              ndd	t        j                         v st        j                  |      rt        j                  |      nd	d
t        j                         v st        j                  t
              rt        j                  t
              nd
t        j                  |      dz  }t        t        j                  |            d}y)u   반환형이 list인지 확인MY_KEY_CvalrR   mr   rY   5assert %(py4)s
{%(py4)s = %(py0)s(%(py1)s, %(py2)s)
}
isinstanceresultlistr   rM   r   r   N)r|   r   r   r~   r   r   r   r   r   r   r   r   r    )r"   r   rP   rQ   r   r%   @py_format5s          r(   test_returns_list_typez0TestGetAvailableProviders.test_returns_list_type   s    :u-3JG
	 Y///1&$''''''''z'''z''''''&'''&''''''$'''$''''''''''r*   c                    |j                  dd       t        ddd      g}t        |      }|j                         }t	        |      }d}||k(  }|st        j                  d|fd	||f      d
t        j                         v st        j                  t              rt        j                  t              nd
dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}y)u/   빈 문자열 API 키는 미설정으로 간주MY_KEY_EMPTY z	empty-keyr   r   rY   r   r   ry   r[   rz   r{   rc   r]   N)r|   r   r   r~   r[   r   r   r   r   r   r   r   r    )
r"   r   rP   rQ   rz   rT   ri   r$   rj   rg   s
             r(   .test_empty_string_key_not_considered_availablezHTestGetAvailableProviders.test_empty_string_key_not_considered_available   s    >2.3NS
	 Y/224	9~""~""""~""""""s"""s""""""9"""9"""~""""""""""r*   r>   )r@   rA   rB   rC   r   r   r   r   rD   r*   r(   rq   rq   j   s    -.
6(#r*   rq   c                   p    e Zd ZdZdefdZddZddZddZddZ	dd	Z
dd
Z	 	 ddZddZddZddZy)	TestRouteu"   route() task_type 매핑 테스트r?   c                     |j                  dd       |j                  dd       |j                  dd       |j                  dd       t               S )	u?   모든 기본 프로바이더 키를 설정한 AuxRouter 반환r
   zsk-ant-testr-   sk-openai-testr<   google-testr7   zdeepseek-test)r|   r   )r"   r   s     r(   _router_with_all_keyszTestRoute._router_with_all_keys   sO    .>+-=>+];-?{r*   Nc                 "   | j                  |      }|j                  d      }d}||u}|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}|j                  }d	}||k(  }	|	st        j                  d
|	fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }
t        t        j                  |
            dx}x}	}y)u%   summarize → Haiku(anthropic) 우선	summarizeNis notz%(py0)s is not %(py3)sr   r   rN   rO   r   r	   r   r   r   r   r   r   router   r   r   r   r   r   r   r    r   r"   r   rQ   r   rT   r#   rU   r&   r$   r%   r'   s              r(   test_summarize_prefers_haikuz&TestRoute.test_summarize_prefers_haiku   s    ++K8k*!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!{{)k){k)))){k))))))v)))v))){)))k)))))))r*   c                 "   | j                  |      }|j                  d      }d}||u}|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}|j                  }d	}||k(  }	|	st        j                  d
|	fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }
t        t        j                  |
            dx}x}	}y)u$   analyze → Sonnet(anthropic) 우선analyzeNr   r   r   r   rO   r   r	   r   r   r   r   r   r   r   s              r(   test_analyze_prefers_sonnetz%TestRoute.test_analyze_prefers_sonnet   s    ++K8i(!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!{{)k){k)))){k))))))v)))v))){)))k)))))))r*   c                 "   | j                  |      }|j                  d      }d}||u}|st        j                  d|fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}|j                  }d	}||k(  }	|	st        j                  d
|	fd||f      dt	        j
                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }
t        t        j                  |
            dx}x}	}y)u$   classify → Haiku(anthropic) 우선classifyNr   r   r   r   rO   r   r	   r   r   r   r   r   r   r   s              r(   test_classify_prefers_haikuz%TestRoute.test_classify_prefers_haiku   s    ++K8j)!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!{{)k){k)))){k))))))v)))v))){)))k)))))))r*   c                    |j                  dd       |j                  dd       |j                  dd       |j                  dd       t               }|j                  d      }d	}||u}|st	        j
                  d
|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d	x}}|j                  }d}||k(  }	|	st	        j
                  d|	fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }
t        t	        j                  |
            d	x}x}	}y	)u7   default → 첫 번째 사용 가능한 프로바이더r
   Fru   r-   r   r<   r7   defaultNr   r   r   r   rO   r   r,   r   r   r   r   r   r}   r|   r   r   r   r   r   r   r   r   r   r    r   r   s              r(   $test_default_returns_first_availablez.TestRoute.test_default_returns_first_available   +   .>+-=>+U;-u=i(!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!{{&h&{h&&&&{h&&&&&&v&&&v&&&{&&&h&&&&&&&r*   c                    |j                  dd       |j                  dd       |j                  dd       |j                  dd       t               }|j                  d      }d	}||u}|st	        j
                  d
|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d	x}}y	)u+   알 수 없는 task_type → default 동작r-   sk-testr
   Fru   r<   r7   completely_unknown_taskNr   r   r   r   rO   r   )r|   r}   r   r   r   r   r   r   r   r   r   r    r"   r   rQ   r   rT   r#   rU   r&   s           r(   ,test_unknown_task_type_falls_back_to_defaultz6TestRoute.test_unknown_task_type_falls_back_to_default   s    +Y7.>+U;-u=78!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!r*   c                    |j                  dd       |j                  dd       |j                  dd       |j                  dd       t               }|j                  d      }d}||u }|st        j                  d	|fd
||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }dd|iz  }t        t        j                  |            dx}}y)u6   사용 가능한 프로바이더 없으면 None 반환r
   Fru   r-   r<   r7   r   Nr.   )z%(py0)s is %(py3)sr   r   rO   r   )r}   r   r   r   r   r   r   r   r   r   r    r   s           r(   3test_route_returns_none_when_no_providers_availablez=TestRoute.test_route_returns_none_when_no_providers_available   s    .>+U;+U;-u=k*v~vvvr*   c                    |j                  dd       |j                  dd       |j                  dd       |j                  dd       t               }|j                  d      }d	}||u}|st	        j
                  d
|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d	x}}|j                  }d}||k(  }	|	st	        j
                  d|	fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }
t        t	        j                  |
            d	x}x}	}y	)u;   summarize: anthropic 없으면 openai(gpt-4o-mini) fallbackr
   Fru   r-   r   r<   r7   r   Nr   r   r   r   rO   r   r,   r   r   r   r   r   r   r   s              r(   8test_summarize_fallback_to_openai_when_anthropic_missingzBTestRoute.test_summarize_fallback_to_openai_when_anthropic_missing   s-    	.>+-=>+U;-u=k*!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!{{&h&{h&&&&{h&&&&&&v&&&v&&&{&&&h&&&&&&&r*   c                    |j                  dd       |j                  dd       |j                  dd       |j                  dd       t               }|j                  d      }d	}||u}|st	        j
                  d
|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d	x}}|j                  }d}||k(  }	|	st	        j
                  d|	fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }
t        t	        j                  |
            d	x}x}	}y	)u,   analyze: anthropic 없으면 openai fallbackr
   Fru   r-   r   r<   r7   r   Nr   r   r   r   rO   r   r,   r   r   r   r   r   r   r   s              r(   ,test_analyze_fallback_when_anthropic_missingz6TestRoute.test_analyze_fallback_when_anthropic_missing   r   r*   c                    |j                  dd       t               }|j                  d      }d}||u}|st        j                  d|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }d	d
|iz  }t        t        j                  |            dx}}t        |t              }|sddt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      nddt        j                         v st        j                  t              rt        j                  t              ndt        j                  |      dz  }	t        t        j                  |	            d}y)u*   route() 반환값이 ProviderConfig 타입r
   r   r   Nr   r   r   r   rO   r   r   r   r   r   )r|   r   r   r   r   r   r   r   r   r   r    r   r   )
r"   r   rQ   r   rT   r#   rU   r&   r%   r   s
             r(   'test_route_returns_provider_config_typez1TestRoute.test_route_returns_provider_config_type   s	   .	:k*!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!&.11111111z111z111111&111&111111.111.1111111111r*   c                    |j                  dd       |j                  dd       |j                  dd       |j                  dd       t               }|j                  d      }d	}||u}|st	        j
                  d
|fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }t        t	        j                  |            d	x}}|j                  }d}||k(  }	|	st	        j
                  d|	fd||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |      dz  }dd|iz  }
t        t	        j                  |
            d	x}x}	}y	)u:   classify: anthropic 없으면 openai, 없으면 google 순r
   Fru   r-   r<   r   r7   r   Nr   r   r   r   rO   r   r;   r   r   r   r   r   r   r   s              r(   test_classify_fallback_chainz&TestRoute.test_classify_fallback_chain  s*   .>+U;+];-u=j)!!vT!!!!vT!!!!!!v!!!v!!!T!!!!!!!{{&h&{h&&&&{h&&&&&&v&&&v&&&{&&&h&&&&&&&r*   r>   )r@   rA   rB   rC   r   r   r   r   r   r   r   r   r   r   r   r   rD   r*   r(   r   r      sK    ,I ***	'"'	'	'2	'r*   r   c                        e Zd ZdZddZddZy)TestCustomProviderRoutingu5   커스텀 프로바이더와 route() 통합 테스트Nc                 l   |j                  dd       t        ddd      g}t        |      }dD ]  }|j                  |      }d}||u}|st	        j
                  d	|fd
||f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      dz  }dd|iz  }	t        t	        j                  |	            dx}}|j                  }d}
||
k(  }|st	        j
                  d|fd||
f      dt        j                         v st	        j                  |      rt	        j                  |      ndt	        j                  |      t	        j                  |
      dz  }	dd|	iz  }t        t	        j                  |            dx}x}}
 y)uW   커스텀 단일 프로바이더 - 모든 task_type에서 해당 프로바이더 반환
CUSTOM_KEYz	sk-customrd   zcustom-modelr   rY   )r   r   r   r   Nr   r   r   r   rO   r   r   r   r   r   r   )r|   r   r   r   r   r   r   r   r   r   r   r    r   )r"   r   rd   rQ   taskr   rT   r#   rU   r&   r$   r%   r'   s                r(   %test_custom_provider_single_availablez?TestCustomProviderRouting.test_custom_provider_single_available  s   <5$(
 V,C 	+D\\$'F!%%6%%%%6%%%%%%6%%%6%%%%%%%%%%;;*(*;(****;(******6***6***;***(*******	+r*   c                    |j                  dd       |j                  dd       t        dddd      t        d	ddd
      g}t        |      }|j                         }t	        |      }d}||k(  }|st        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      dz  }dd|iz  }	t        t        j                  |	            dx}x}}|D 
cg c]  }
|
j                   }}
d}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}d	}||v }|st        j                  d|fd||f      t        j                  |      dt        j                         v st        j                  |      rt        j                  |      nddz  }dd|iz  }t        t        j                  |            dx}}yc c}
w )uK   priority 높은 프로바이더가 get_available_providers 결과에 포함KEY_LOWval1KEY_HIGHval2lowr   rZ   )r   r   r   r3   high
   rY      r   ry   r[   rz   r{   rc   r]   NrH   rJ   rK   rL   rO   r   )r|   r   r   r~   r[   r   r   r   r   r   r   r   r    r   )r"   r   rP   rQ   rz   rT   ri   r$   rj   rg   rR   rK   rS   rU   r&   s                  r(   'test_priority_ordering_in_get_availablezATestCustomProviderRouting.test_priority_ordering_in_get_available%  s   9f-:v.SiRSTczTVW
	 Y/224	9~""~""""~""""""s"""s""""""9"""9"""~""""""""""!*+A++u~uuvvv ,s   3Kr>   )r@   rA   rB   rC   r   r   rD   r*   r(   r   r     s    ?+ r*   r   )rC   builtinsr   _pytest.assertion.rewrite	assertionrewriter   ossyspathlibr   pytestpathinsertstr__file__parentutils.aux_llm_routerr   r   r   rF   rq   r   r   rD   r*   r(   <module>r      s   
  	 
   3tH~,,33::; < :+$ +$f* *@0# 0#ph' h'`   r*   