
    Xj2                        d dl Z d dlmZmZmZmZmZmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZmZmZmZ d dlmZ d dlmZmZmZ d d	lmZmZmZmZmZmZm Z   e	e!          Z" ed
g          Z#dede$fdZ%dede$fdZ&e#'                    de(e                    edd           ee           e ed                    fde)dz  dedefd            Z*e#'                    de(e                    ee           e ed
                     edd          fdedede)dz  fd            Z+e#'                    de           ee           e ed
                    fde,d ededefd!            Z-e#.                    deej/        "           ee           e ed
                    fdededefd#            Z0e#1                    de           ee           e ed
                    fde,de d ededef
d$            Z2e#.                    d%e           ee           e ed
                    fde,d&ed ededef
d'            Z3e#4                    dej5        (           ee           e ed
                    fde,d ededefd)            Z6e#'                    d*e(e                    ee           e ed                    fde,dedefd+            Z7e#.                    d*eej/        "           ee           e ed                    fde,ded ededef
d,            Z8e#1                    d-e           ee           e ed                    fd.e,ded ededef
d/            Z9e#.                    d0ej5        (           ee           e ed
                    fde,d ededefd1            Z:e#4                    d-ej5        (           ee           e ed                    fd.e,d ededefd2            Z;e#.                    d3ej5        (           ee           e ed                    fd.e,d ededefd4            Z<dS )5    N)	APIRouterDependsHTTPExceptionQueryRequeststatus)
get_logger)Session)get_db)require_createrequire_deleterequire_readrequire_update)get_translator)ModelModelProviderUser)ModelCreateModelResponseModelUpdateProviderConfigProviderCreateProviderResponseProviderUpdate	providers)tagsproviderreturnc                 h   i d| j         d| j        d| j        d| j        d| j        d| j        d| j        d| j        d	| j        d
| j	        d| j
        d| j        d| j        d| j        d| j        pg d| j        d| j        | j        | j        | j        d | j        pg D             dS )Nidnamedescriptioniconcolordefault_base_url
configuredapi_keybase_urlpriorityenabledprovider_kindprotocol	auth_typecapabilitiesis_localhealthcheck_pathc                 ,    g | ]}t          |          S  _model_to_response.0models     ?/lsinfo/ai/hellotax_ai/base_platform/app/api/v1/ai/providers.py
<listcomp>z)_provider_to_response.<locals>.<listcomp>/   s!    PPP%e,,PPP    )extra_config
created_at
updated_atmodels)r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r;   r<   r=   r>   )r   s    r8   _provider_to_responser?      sC   hk 	x+ 		
 	 	H5 	h) 	8# 	H% 	H% 	8# 	/ 	H% 	X' 	-3  	H%!" 	H5#$ !-))PP(/:ORPPP+   r:   r7   c                 p   i d| j         d| j        d| j        d| j        d| j        pg d| j        d| j        d| j        d	| j        d
| j	        d| j
        d| j        d| j        d| j        d| j        d| j        r| j        j        nd d| j        r| j        j        nd| j        | j        dS )Nr    coder!   typer   r*   	dimensionremote_model_idcontext_lengthmax_output_tokenssupports_streamsupports_toolsr)   r;   provider_idprovider_namer/   F)r<   r=   )r    rA   r!   rB   r   r*   rC   rD   rE   rF   rG   rH   r)   r;   rI   r   r/   r<   r=   )r7   s    r8   r4   r4   3   s=   eh
 	
 	
	
 	
 b 	5= 	U_ 	50 	%. 	U4 	50 	%. 	EN 	* 	u(  	H,,D!" 	u~HEN++5#$ &&'   r:   z/models/available)response_modelz0Filter by model type (e.g., 'embedding', 'chat'))r"   r>   rB   dbcurrent_userc                    |                     t                                        t                                        t          j        t          j        t          j                  }| r#|                    t          j        | k              }|                    t          j	        
                                t          j        
                                                                          }d |D             S )Nc                 ,    g | ]}t          |          S r2   r3   r5   s     r8   r9   z(get_available_models.<locals>.<listcomp>]   !    :::%u%%:::r:   )queryr   joinr   filterr*   r&   rB   order_byr)   ascr    all)rB   rL   rM   rQ   r>   s        r8   get_available_modelsrW   K   s     		m			M=3]5J

 

 
  1UZ4/00^^EN..00%(,,..AAEEGGF::6::::r:   /z-Filter by capability: chat, embedding, rerank
capabilityc                 x   |                      t                    }|r3|                    t          j                            |g                    }|                    t          j                                        t          j                                                  	                                }d |D             S )Nc                 ,    g | ]}t          |          S r2   )r?   )r6   r   s     r8   r9   z!get_providers.<locals>.<listcomp>l   s!    FFF!(++FFFr:   )
rQ   r   rS   r.   containsrT   r)   rU   r    rV   )rL   rM   rY   rQ   r   s        r8   get_providersr]   `   s     HH]##E P]7@@*NNOO}599;;]=M=Q=Q=S=STTXXZZIFFIFFFFr:   z/{provider_id}rI   requestc                 $   t          |          }|                    t                                        t          j        | k                                              }|s$t          d|                    d                    t          |          S )N  provider.not_foundstatus_codedetail)	r   rQ   r   rS   r    firstr   tr?   )rI   r^   rL   rM   rf   r   s         r8   get_providerrg   o   s{     	wAxx&&--m.>+.MNNTTVVH OACC8L4M4MNNNN ***r:   )rK   rc   c                    t                               | j        |j                                      d           |                                 }|                    dd           }t          di |}|r|                    |           d|_	        |
                    |           |                                 |                    |           t                               |j                                      d           t          |          S )N)rJ   user_idzCreating providerr'   TrI   zProvider createdr2   )loggerbindr!   r    info
model_dumppopr   set_api_keyr&   addcommitrefreshr?   )r   rL   rM   payloadr'   db_providers         r8   create_providerrv   }   s     KKhm\_KEEJJK^___!!##Gkk)T**G**'**K &(((!%FF;IIKKKJJ{
KKKNK++001CDDD ---r:   c                    t          |          }t                              | |j                                      d           |                    t                                        t          j        | k                                              }|sRt                              |           	                    d           t          d|                    d                    |                    d	                                          D ]T\  }}|d
k    r8|                    |           t          |p|j        p|j                  |_        Ct'          |||           U|                                 |                    |           t                              |                               d           t-          |          S )NrI   ri   zUpdating providerrj   zProvider not found for updater`   ra   rb   Texclude_unsetr'   zProvider updated)r   rk   rl   r    rm   rQ   r   rS   re   warningr   rf   rn   itemsrp   boolr(   r/   r&   setattrrr   rs   r?   )	rI   r   r^   rL   rM   rf   ru   keyvalues	            r8   update_providerr      s    	wA
KKKKAAFFGZ[[[((=))001A[1PQQWWYYK O,,445TUUUACC8L4M4MNNNN)))==CCEE ) )
U)##E***%)%*_;3G*_;K_%`%`K"S%((((IIKKKJJ{
KKKK((--.@AAA ---r:   z/{provider_id}/configureconfigc                 |   t          |          }t                              | |j                                      d           |                    t                                        t          j        | k                                              }|sRt                              |           	                    d           t          d|                    d                    |j        r|                    |j                   |j        p|j        |_        |j        |_        |j        |_        t%          |j        p|j        p|j                  |_        |                                 |                    |           t                              |                               d           t/          |          S )	Nrx   zConfiguring providerrj   z$Provider not found for configurationr`   ra   rb   zProvider configured)r   rk   rl   r    rm   rQ   r   rS   re   r{   r   rf   r'   rp   r(   r%   r)   r*   r}   r/   r&   rr   rs   r?   )rI   r   r^   rL   rM   rf   ru   s          r8   configure_providerr      sw    	wA
KKKKAAFFG]^^^((=))001A[1PQQWWYYK O,,445[\\\ACC8L4M4MNNNN~ 0///!?Jk.JK!?K .K!K 4K8K K IIKKKJJ{
KKKK((--.CDDD ---r:   )rc   c                    t          |          }t                              | |j                                      d           |                    t                                        t          j        | k                                              }|sRt                              |           	                    d           t          d|                    d                    |                    |           |                                 t                              |                               d           d	|                    d
          dS )Nrx   zDeleting providerrj   zProvider not found for deletionr`   ra   rb   zProvider deletedTzprovider.deletedsuccessmessage)r   rk   rl   r    rm   rQ   r   rS   re   r{   r   rf   deleterr   )rI   r^   rL   rM   rf   ru   s         r8   delete_providerr      s    	wA
KKKKAAFFGZ[[[((=))001A[1PQQWWYYK O,,445VWWWACC8L4M4MNNNNIIkIIKKK
KKKK((--.@AAA,>(?(?@@@r:   z/{provider_id}/modelsc                     |                     t                                        t          j        | k                                              }d |D             S )Nc                 ,    g | ]}t          |          S r2   r3   r5   s     r8   r9   z'get_provider_models.<locals>.<listcomp>   rP   r:   )rQ   r   rS   rI   rV   )rI   rL   rM   r>   s       r8   get_provider_modelsr      sI     XXe__##E$5$DEEIIKKF::6::::r:   c                    t          |          }t                              | |j        |j                                      d           |                    t                                        t          j        | k              	                                }|sRt                              |           
                    d           t          d|                    d                    t          d
i |                                }|                    |           |                                 |                    |           t                              | |j                                      d	           t%          |          S )N)rI   
model_coderi   zAdding model to providerrj   z%Provider not found for model additionr`   ra   rb   )rI   model_idzModel added to providerr2   )r   rk   rl   rA   r    rm   rQ   r   rS   re   r{   r   rf   r   rn   rq   rr   rs   r4   )rI   r7   r^   rL   rM   rf   r   db_models           r8   	add_modelr      s@    	wA
KKKEJKXX]]^xyyyxx&&--m.>+.MNNTTVVH O,,445\]]]ACC8L4M4MNNNN**u''))**HFF8IIKKKJJx
KKK(+K>>CCD]^^^h'''r:   z/models/{model_id}r   c                    t          |          }|                    t                                        t          j        | k                                              }|s$t          d|                    d                    |                    d          	                                D ]\  }}t          |||           |                                 |                    |           t          |          S )Nr`   model.not_foundrb   Try   )r   rQ   r   rS   r    re   r   rf   rn   r|   r~   rr   rs   r4   )	r   r7   r^   rL   rM   rf   r   r   r   s	            r8   update_modelr      s     	wAxx%%eh(&:;;AACCH LACC8I4J4JKKKK&&T&::@@BB & &
U#u%%%%IIKKKJJxh'''r:   z/{provider_id}/health-checkc                   K   t          |          }|                    t                                        t          j        | k                                              }|s$t          d|                    d                    |j        p|j	        }|st          dd          |j
        pd}|                    d           |                    d          r|nd|z    }i }	|                                }
|j        dk    r|
r	d	|
 |	d
<   n%|j        dk    r|
r|
|	d<   n|j        dk    r|
r|
|	d<   	 t          j        d          4 d {V }|                    ||	           d {V }d d d           d {V  n# 1 d {V swxY w Y   t$                              d|  d|j                    |j        |j        |dS # t,          $ r:}t$                              d|  d|            t          dd|           d d }~ww xY w)Nr`   ra   rb   i  zProvider base URL is requiredz/healthrX   bearerzBearer Authorizationr'   zapi-key	x_api_keyz	x-api-keyg      $@)timeout)headersz#Provider health check: provider_id=z	, status=)r   rc   urlz*Provider health check failed: provider_id=z, error=i  zHealth check failed: )r   rQ   r   rS   r    re   r   rf   r(   r%   r0   rstrip
startswithget_api_keyr-   httpxAsyncClientgetrk   rm   rc   
is_success	Exceptionerror)rI   r^   rL   rM   rf   r   r(   pathr   r   r'   clientresponseexcs                 r8   health_check_providerr     s      	wAxx&&--m.>+.MNNTTVVH OACC8L4M4MNNNN =H$=H U4STTTT$1	D__S!!
SDOOC,@,@$PDDcDj
S
SCG""$$GX%%'%#6W#6#6  		y	(	(W	($			{	*	*w	*&]$T222 	> 	> 	> 	> 	> 	> 	>f#ZZWZ========H	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	> 	>f+ffPXPdffggg#.x?S\_``` ] ] ]\+\\WZ\\]]]4QC4Q4QRRRX\\]s<   4G E?-G ?
F		G F	7G 
H	5HH	c                    t          |          }|                    t                                        t          j        | k                                              }|s$t          d|                    d                    |                    |           |	                                 d|                    d          dS )Nr`   r   rb   Tzmodel.deletedr   )
r   rQ   r   rS   r    re   r   rf   r   rr   r   r^   rL   rM   rf   r   s         r8   delete_modelr   1  s     	wAxx%%eh(&:;;AACCH LACC8I4J4JKKKKIIhIIKKKO(<(<===r:   z/models/{model_id}/togglec                    t          |          }|                    t                                        t          j        | k                                              }|s$t          d|                    d                    |j         |_        |	                                 |
                    |           d|j        dS )Nr`   r   rb   T)r   r*   )r   rQ   r   rS   r    re   r   rf   r*   rr   rs   r   s         r8   toggle_modelr   A  s     	wAxx%%eh(&:;;AACCH LACC8I4J4JKKKK#++HIIKKKJJx(8999r:   )=r   fastapir   r   r   r   r   r   common_loggingr	   sqlalchemy.ormr
   app.api.depsr   app.api.permissionsr   r   r   r   app.core.i18nr   
app.modelsr   r   r   app.schemasr   r   r   r   r   r   r   __name__rk   routerdictr?   r4   r   liststrrW   r]   intrg   postHTTP_201_CREATEDrv   putr   r   r   HTTP_200_OKr   r   r   r   r   r   r   r2   r:   r8   <module>r      s    M M M M M M M M M M M M M M M M % % % % % % " " " " " "       \ \ \ \ \ \ \ \ \ \ \ \ ( ( ( ( ( ( 1 1 1 1 1 1 1 1 1 1                  
H				&	&	&M d    4e     0 ]0CDDuL   '&// h!7!788; ;
*; 		;
 ; ; ; ED;( C%5 677'&// k!:!:;;"UI  G GGG d
G G G 87G -=>> '&// k!:!:;;	
+ 
+
+
+ 	
+ 	
+ 
+ 
+ ?>
+ S!1v?VWW '&// !<!<==. ... . . . XW.& -=>>
 '&// !<!<==. ... . 		.
 . . . ?>.2 '8HII
 '&// !<!<==. ... . 		.
 . . . JI.6 V-?@@ '&// !<!<==	A AAA 	A 	A A A A@A$ #D4GHH '&// h!7!788; ;;; ; ; ; IH; MvG^    '&// !9!9::( ((( ( 		(
 ( ( ( (*  ??
 '&// !9!9::( ((( ( 		(
 ( ( ( @?($ *8JKK '&// !<!<==	] ]]] 	] 	] ] ] LK]B #1CDD '&// !9!9::	> >>> 	> 	> > > ED> (f6HII '&// !9!9::	: ::: 	: 	: : : JI: : :r:   