
    AHj                         d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
mZ d dlmZ dee   defdZdefdZ ej&                  d	      Zd
edefdZdefdZdefdZ G d d      Zy)    N)Path)Optional)loggervaluereturnc                 ,    | y| j                         dv S )NF)true1tyyes)lower)r   s    R/root/tools/cai/cai_env/lib/python3.12/site-packages/litellm_proxy_extras/utils.pystr_to_boolr      s    };;=:::    c                      t         j                  j                         } t        t        j                  d            rd| d<   t        j                  dd      | d<   | S )zJGet environment variables for Prisma, handling offline mode if configured.PRISMA_OFFLINE_MODEr	   NPM_CONFIG_PREFER_OFFLINENPM_CONFIG_CACHEz/app/.cache/npm)osenvironcopyr   getenv)
prisma_envs    r   _get_prisma_envr      sQ    "J29923428
./)+ 1*

%& r   z
^(\d{14})_namec                 h    t         j                  |       }|rt        |j                  d            S dS )u   Extract the leading `YYYYMMDDHHMMSS` timestamp from a migration name.

    Returns 0 if the name doesn't match the Prisma pattern — unexpected-format
    entries sort as "oldest" and are treated as historical.
       r   )_MIGRATION_TS_REmatchintgroup)r   ms     r   _migration_timestampr$   $   s-     	t$A3qwwqz?&Q&r   c                 ,    | syt        d | D              S )z<Max timestamp in a set/list of migration names (0 if empty).r   c              3   2   K   | ]  }t        |        y w)N)r$   ).0ns     r   	<genexpr>z+_max_migration_timestamp.<locals>.<genexpr>2   s     61#A&6s   )max)namess    r   _max_migration_timestampr,   .   s    6666r   c                     t        t        j                  d            rd} t        j                  d      }|r9t        j                  j	                  |      rt        j                  d|        |S t        j                  j	                  |       rt        j                  d|         | S t        j                  d|  d       y)	zHGet the Prisma command to use, bypassing Python wrapper in offline mode.r   z;/app/.cache/prisma-python/binaries/node_modules/.bin/prismaPRISMA_CLI_PATHzUsing custom Prisma CLI at zUsing cached Prisma CLI at zPrisma CLI not found at z8. Falling back to Python wrapper (may attempt downloads)prisma)r   r   r   pathexistsr   infowarning)default_cli_pathcustom_cli_paths     r   _get_prisma_commandr6   5   s    299234X ))$56rww~~o>KK5o5FGH"" 77>>*+KK56F5GHI## 	&'7&8 9E E	
 r   c                   H   e Zd Zedefd       Zededefd       Zededefd       Z	edefd       Z
edefd	       Zed
edefd       Zed
edefd       Ze	 ddededefd       Zededefd       Zededdfd       Zededefd       Ze	 ddededefd       Zy)ProxyExtrasDBManagerr   c                  <   t        j                  d      } t         j                  j                  t              }| rt         j                  j                  |       rt        j                  |      D ]  }t         j                  j                  ||      }t         j                  j                  | |      }t         j                  j                  |      rt        j                  ||d       {t        j                  ||        | S t        j                  ||        | S |S )z
        Get the path to the migrations directory

        Set os.environ["LITELLM_MIGRATION_DIR"] to a custom migrations directory, to support baselining db in read-only fs.
        LITELLM_MIGRATION_DIRT)dirs_exist_ok)r   r   r0   dirname__file__r1   listdirjoinisdirshutilcopytreecopy2)custom_migrations_dirpkg_migrations_diritemsrc_pathdst_paths        r   _get_prisma_dirz$ProxyExtrasDBManager._get_prisma_dirQ   s     !#		*A BWW__X6 ww~~34JJ'9: 9D!ww||,>EH!ww||,A4HHww}}X.($OXx89 )(  24IJ((!!r   schema_pathc           	         t         j                         }t        |      }|dz  dz  }|j                  dd       t	        j
                  d      }|st        j                  d       yt               }	 t        j                  d       |d	z  }t        j                  t               d
ddd|dgt        |d      dd|       t        j                  d       t        j                  t               d
dddgdd|       y# t        j                  $ r t        j                  d       Y yt        j                   $ r9}t        j                  d| d|j"                   d|j$                          |d}~ww xY w)z4Create a baseline migration for an existing database
migrations0_initT)parentsexist_okDATABASE_URLDATABASE_URL not setFz Generating baseline migration...migration.sqlmigratediffz--from-emptyz--to-url--scriptw   )stdoutchecktimeoutenvz(Marking baseline migration as applied...resolve	--applied)rY   rZ   r[   z=Migration timed out - the database might be under heavy load.z#Error creating baseline migration: , N)r8   rI   r   mkdirr   r   r   errorr   r2   
subprocessrunr6   openTimeoutExpiredr3   CalledProcessErrorstderrrX   )rJ   
prisma_dirprisma_dir_pathinit_dirdatabase_urlr   migration_filees           r   _create_baseline_migrationz/ProxyExtrasDBManager._create_baseline_migrationl   sk    *99;
z*"\1H< 	td3yy0LL/0$&
-	KK:;%7NNN')"  NC0" KKBCNN')  (( 	NNO ,, 	NN5aS188*BqxxjQ G		s   3BC< <(E1&E184E,,E1migrations_dirc                     t        j                   |  d      }t        j                  dt        |       d|         |D cg c]!  }t	        |      j
                  j                  # c}S c c}w )z<Get all migration directory names from the migrations folderz/migrations/*/migration.sqlzFound z migrations at )globr   r2   lenr   parentr   )rn   migration_pathsps      r   _get_migration_namesz)ProxyExtrasDBManager._get_migration_names   s]     ))~&66Q$RSfS12/.AQRS-<=Q##===s   &A*migration_namec                 f    t               }t        j                  t               ddd| gddd|       y)z(Mark a specific migration as rolled backrS   r\   --rolled-back<   TrZ   rY   capture_outputr[   Nr   ra   rb   r6   rv   r   s     r   _roll_back_migrationz)ProxyExtrasDBManager._roll_back_migration   s=     %&
#% 	
r   c                 f    t               }t        j                  t               ddd| gddd|       y)z$Mark a specific migration as appliedrS   r\   r]   ry   Trz   Nr|   r}   s     r   _resolve_specific_migrationz0ProxyExtrasDBManager._resolve_specific_migration   s5     %&
 "Iy+~V	
r   error_messagec                 h    g d}|D ])  }t        j                  || t         j                        s) y y)aw  
        Check if the error message indicates a database permission error.

        Permission errors should NOT be marked as applied, as the migration
        did not actually execute successfully.

        Args:
            error_message: The error message from Prisma migrate

        Returns:
            bool: True if this is a permission error, False otherwise
        )zDatabase error code: 42501zmust be owner of tablezpermission denied for schemazpermission denied for tablezmust be owner of schemaTFresearch
IGNORECASE)r   permission_patternspatterns      r   _is_permission_errorz)ProxyExtrasDBManager._is_permission_error   s7    
 + 	Gyy-?	 r   c                 h    g d}|D ])  }t        j                  || t         j                        s) y y)a  
        Check if the error message indicates an idempotent operation error.

        Idempotent errors (like "column already exists") mean the migration
        has effectively already been applied, so it's safe to mark as applied.

        Args:
            error_message: The error message from Prisma migrate

        Returns:
            bool: True if this is an idempotent error, False otherwise
        )zalready existszcolumn .* already existszduplicate key value violateszrelation .* already existszconstraint .* already existszdoes not existz.Can't drop database.* because it doesn't existTFr   )r   idempotent_patternsr   s      r   _is_idempotent_errorz)ProxyExtrasDBManager._is_idempotent_error   s7    
 + 	Gyy-?	 r   mark_all_appliedc                 4	   t        j                  d      }|st        j                  d       yt        j                  d      xs |}t	        t        j                  d            }|dz  }	 t        j                  d       t        |d	      5 }t        j                  t               d
dd|d|dgdd|t                      ddd       |j#                         st        j                  d       t%        t	        |       j'                  d            }	|	D ]j  }
	 t        j                  t               dddt)        |
      d|gddddt                      t        j                  d|
j*                  j,                          l yt        j                  d |        	 t        j                  d!       t        j                  t               dddt)        |      d|gddddt                     }t        j                  d"|j.                          t        j                  d#       |syt0        j3                  |       }t        j                  d&t5        |       d'       |D ]c  }	 t        j                  d(|        t        j                  t               d
d)d*|gddddt                      t        j6                  d+|        e y# 1 sw Y   xY w# t        j                  $ r-}t        j                  d|j                          Y d}~Cd}~wt        j                   $ r t        j                  d       Y qw xY w# t        j                  $ rD}t        j                  d|
j*                  j,                   d|j                          Y d}~}d}~wt        j                   $ r1 t        j                  d|
j*                  j,                   d       Y w xY w# t        j                  $ r-}t        j                  d$|j                          Y d}~d}~wt        j                   $ r t        j                  d%       Y "w xY w# t        j                  $ r>}d,|j                  vr%t        j                  d-| d|j                          Y d}~6d}~ww xY w).z
        1. Compare the current database state to schema.prisma and generate a migration for the diff.
        2. Run prisma migrate deploy to apply any pending migrations.
        3. Mark all existing migrations as applied.
        rP   rQ   N
DIRECT_URLlitellm_migration_diff_)prefixrR   z9Generating migration diff between DB and schema.prisma...rV   rS   rT   z
--from-urlz--to-schema-datamodelrU   Try   )rY   rZ   rX   r[   z#Failed to generate migration diff: z$Migration diff generation timed out.u   Migration diff was not created (prisma migrate diff failed — likely a pooler URL). Falling back to direct SQL execution of each migration file.z*/migration.sqldbexecutez--filez--schemarZ   rY   r{   textr[   zApplied migration: zFailed to apply migration : 
Migration z timed out.zMigration diff created at z8Running prisma db execute to apply the migration diff...zprisma db execute stdout: u'   ✅ Migration diff applied successfullyz Failed to apply migration diff: z%Migration diff application timed out.z
Resolving z migrationszResolving migration: r\   r]   zResolved migration: z/is already recorded as applied in the database.Failed to resolve migration )r   r   r   r`   r   tempfilemkdtempr2   rc   ra   rb   r6   r   re   r3   rf   rd   r1   sortedrp   strrr   r   rX   r8   ru   rq   debug)rn   rJ   r   rj   diff_urldiff_dirdiff_sql_pathfrl   migration_filesmig_fileresultmigration_namesrv   s                 r   _resolve_all_migrationsz,ProxyExtrasDBManager._resolve_all_migrations
  s!    yy0LL/0 99\*:l((0IJK ?2	CKKSTmS) Q+-!$ /#"	 '). ##%NN' %T.%9%>%>?P%QRO+ SSNN/1 %$M&' !#"'+!+-  KK"5hoo6J6J5K LM%S2 0@A	DKKRS^^')& ##%F  KK4V]]ODEKKAB  .CCNSj_!5 6kBC- 	N3N3CDE+-!!#& #'') 3N3CDE#	y " ,, 	MNN@
KLL(( 	CNNAB	CB "44 NN4X__5I5I4J"QXXJW  "00 SNNZ0D0D/E[#QRS4 ,, 	JNN=ahhZHII(( 	DNNBC	D4 00 DAHHTNN6~6Fb
Ss   ,!K 3K K A'L=BO  A QKK L:#"L+L:9L:=O9NAOOQ,"P+QQR3RRurlc                     ddl m}m}m}m}  ||       }|j
                  s| S h d} ||j
                        D cg c]  \  }}||v s||f }	}} ||j                   ||	                  S c c}}w )zRemove Prisma-specific query params (connection_limit, pool_timeout,
        schema, etc.) from DATABASE_URL so psycopg can parse it.r   )urlparse
urlunparse	parse_qsl	urlencode>   sslkeyoptionsservicesslcertsslmode
gssencmode
krbsrvnamesslpasswordsslrootcertclient_encodingconnect_timeoutapplication_nametarget_session_attrs)query)urllib.parser   r   r   r   r   _replace)
r   r   r   r   r   parsedlibpq_paramskvkepts
             r   _strip_prisma_query_paramsz/ProxyExtrasDBManager._strip_prisma_query_params  st     	LK#||J
 $-V\\#:P41aa<>OAPP&//	$/@AA Qs   A0	A0Nc           	      6   t        j                  d      }|sy	 ddl}t        j                  |      }t        t        j                  |             }	 |j                  |dd      5 }	 |j                  d      j                         }	 ddd       D ch c]  }|d   	 }}||z
  }	|	syt        |      }
|	D ch c]  }t!        |      |
kD  s| }}|syt#        |      }t%        j&                  dt)        |      d	j+                  |dd
       t)        |      d
kD  r	dz          ydz          y# t        $ r Y yw xY w# |j                  j                  $ r Y ddd       yw xY w# 1 sw Y   xY w# |j                  |j                  f$ r Y yw xY wc c}w c c}w )u_  
        Log a warning if _prisma_migrations contains applied migrations with
        timestamps newer than every migration this build ships.

        This is informational only for the v2 resolver — it tells the operator
        the DB was likely migrated by a newer deployment, which is usually a
        signal that this (older) version shouldn't run against it. We do NOT
        block startup: many users have weird _prisma_migrations state from
        prior thrashing bugs, and blocking them would be a breaking change.

        Safe no-op if psycopg isn't installed or DB isn't reachable.
        rP   Nr   
   T)r   
autocommitzfSELECT migration_name FROM _prisma_migrations WHERE finished_at IS NOT NULL AND rolled_back_at IS NULLaG  Database has %d migration(s) applied that are NEWER than any migration this LiteLLM version ships. This usually means the database was migrated by a newer LiteLLM deployment. Some API endpoints may fail because this proxy's Prisma client does not know about those schema changes. Consider upgrading this deployment. Unknown: %sr^      z ... )r   r   psycopgImportErrorr8   r   setru   connectr   fetchallerrorsUndefinedTableOperationalErrorDatabaseErrorr,   r$   r   r   r3   rq   r?   )rn   rj   r   cleaned_urlknownconnrowsrappliedunknownhead_newest_tsr   hostilesorted_hostiles                 r   _warn_if_db_ahead_of_headz.ProxyExtrasDBManager._warn_if_db_ahead_of_head  s    yy0	 +EElS(==nMN	
 RD !  	<<S hj 		" "&&A1Q4&&E/1%8$
(<T(B^(SD
 
 & LIInRa()s>7JQ7NVW		
 UWW		
S  		& ~~44 	 		 	 (('*?*?@ 	
 	 '
sq   D. E0 &E$(D=E0 F9FF.	D:9D:=E!E$E0  E!!E$$E-)E0 0FFuse_migratec           
      	   t         j                         dz   }t         j                         }| snt        j                         }t        j                  |       	 t        j                  t               dddgddt                      	 t        j                  |       yt         j                  |       t        j                         }t        j                  |       	 t        d
      D ]i  }	 t        j                  t               ddgddddt                     }t        j                  d|j                            t        j                  |       y t        d#      # t
        j                  t
        j                  f$ r}t        d|       |d	}~ww xY w# t        j                  |       w xY w# t
        j                  $ rI t        j                  d|dz    d       t#        j$                  t'        j(                  dd             Y &t
        j                  $ r}|j*                  xs d}d|v r4d|v r0t        j                  d       t         j-                  |       Y d	}~d|v r t/        j0                  d|      }|rt         j3                  |      r|j5                  d      }	t        j                  d|	 d       	 t         j7                  |	       n)# t
        j                  t
        j                  f$ r Y nw xY w	 t         j9                  |	       n=# t
        j                  t
        j                  f$ r}
t        d|	 d|
       |
d	}
~
ww xY wY d	}~wt        d|       |d|v r$t         j;                  |      rt        d |       |t/        j0                  d!|      }|rt         j3                  |      r|j5                  d      }	t        j                  d|	 d"       	 t         j7                  |	       n)# t
        j                  t
        j                  f$ r Y nw xY w	 t         j9                  |	       n=# t
        j                  t
        j                  f$ r}
t        d|	 d|
       |
d	}
~
ww xY wY d	}~t        d|       |t        d|       |d	}~ww xY w# t        j                  |       w xY w)$u  
        v2 migration resolver (opt-in via --use_v2_migration_resolver).

        Runs `prisma migrate deploy` and handles standard recovery paths
        (P3005 baseline, P3009/P3018 idempotent errors). Critically, it does
        NOT call `_resolve_all_migrations` — the diff-and-force recovery that
        caused schema thrashing when two LiteLLM versions contended for the
        same DB during rolling deploys.

        Ahead-of-HEAD state (DB has migrations newer than this build ships)
        is logged as a warning, not a fatal error — users whose DBs got into
        weird shapes from the old thrashing should still be able to start.
        /schema.prismar   push--accept-data-lossry   T)rZ   rY   r[   z prisma db push failed.

Detail: N   rS   deployr   prisma migrate deploy stdout: zprisma migrate deploy attempt r   z timed out, retryingr      r   P3005database schema is not emptyu<   Schema exists but no migrations ledger — creating baselineP3009z`(\d+_\S+?)`r   u5    failed idempotently — marking applied and retryingzFailed to mark migration zU as applied after idempotent recovery. Manual intervention may be required.

Detail: zeDatabase migration failed and cannot be auto-recovered. Manual intervention required.

Prisma error:
P3018zzDatabase migration failed due to insufficient permissions. Please grant the required privileges and retry.

Prisma error:
zMigration name: (\d+_\S+)u:    SQL hit idempotent error — marking applied and retryingzDatabase migration failed after 4 attempts (retry loop exhausted by timeouts or repeated idempotent-recovery continues). Check database connectivity, load, and _prisma_migrations ledger state.)r8   rI   r   getcwdchdirra   rb   r6   r   re   rd   RuntimeErrorr   ranger   r2   rX   timesleeprandom	randrangerf   rm   r   r   r   r"   r~   r   r   )r   rJ   rn   original_dirrl   attemptr   rf   migration_matchr   resolve_errs              r   _setup_database_v2z'ProxyExtrasDBManager._setup_database_v2  s    +::<?OO-==?99;LHH^$'(*D&:NO')	  & 	66~Fyy{
 @	# 8 vu'^^,.	8D ""'+!+-F KK"@ PQh HH\"vp 3 O --)) T #%Gs#KLRSST &* "00 KK81EYZ JJv//267!44 bXX^F&(-Kv-UZ -GGT &(*,))OV*L+ 4 I I& Q#2#8#8#;D"KK",TF2g h% 4 I I$ O * = = * 9 9$ % !%	%
3 4 P PQU V * = = * 9 9$ 3 '3&?v F/ 0;m%='"
 (3!33 %*OOUhX  !!
 &(/DDVL".!@@Fx!I# $%	% +-))8&+ , 4 I I& Q#2#8#8#;D"KK",TF2l m% 4 I I$ O * = = * 9 9$ % !%	%
3 4 P PQU V * = = * 9 9$ 	3 '3&?v F/ 0;m%='"
 (3!3		3 %*OOUhX  !!
 'KKQ(T bV HH\"s  -E R, *AF1:R, R, #F FFF F.1AR)	R, R)AR$!R, 'AR$KR$#L =R$?L  R$LR$#M=MMR$R, BR$-PR$#P)&R$(P))R$-QR$#Q=&Q88Q==R$ R, R$$R))R, ,Suse_v2_resolverc                    |r+t        j                  d       t        j                  |       S t        j	                         dz   }t        d      D ]  }t        j                         }t        j	                         }t        j                  |       	 | rt        j                  d       	 t        j                  t               ddgdd	d	d	t               
      }t        j                  d|j                          t        j                  d       d|j                  v r-t        j                  d       	 t        j                  |        y	t        j                  d       t        j                  ||d       t        j                  d       	 t        j                  |        y	t        j                  t               d9d:d;gdd	<       	 t        j                  |        y	 y# t        j                  $ r^}t        j                  d|j                    d|j                          d|j                   v rt#        j$                  d|j                         }|r|j'                  d      }	t        j)                  |j                         rt        j                  d|	 d       	 t        j+                  |	       nL# t        j                  t        j,                  f$ r&}
t        j.                  d|	 d|
 d       Y d}
~
nd}
~
ww xY w	 t        j1                  |	       t        j                  d|	 d       nK# t        j                  t        j,                  f$ r%}t        j.                  d |	 d|        Y d}~nd}~ww xY wt        j                  ||d       nt        j                  d!|	 d"       t        j                  t               dd#d$|	gdd	d	d	t               
       t        j                  d|	 d%       nMd&|j                   v rd'|j                   v rt        j                  d(       t        j3                  |       t        j                  d)       t        j                  ||       t        j                  d*       Y d}~t        j                  |        y	d+|j                   v rt        j5                  |j                         rt#        j$                  d,|j                         }|r|j'                  d      nd-}t        j6                  d.| d/|j                           |r^	 t        j+                  |       t        j                  d| d0       n.# t8        $ r"}t        j.                  d1|        Y d}~nd}~ww xY wt;        d2| d3      |t        j)                  |j                         rqt        j                  d4       t#        j$                  d,|j                         }|r\|j'                  d      }	 t        j                  d5|        t        j+                  |       nL# t        j                  t        j,                  f$ r&}
t        j.                  d| d|
 d       Y d}
~
nd}
~
ww xY w	 t        j                  d6| d7       t        j1                  |       t        j                  d| d       nK# t        j                  t        j,                  f$ r%}t        j.                  d | d|        Y d}~nd}~ww xY wt        j                  ||d       n#t        j.                  d8|j                            Y d}~nd}~ww xY wn# t        j,                  $ rH t        j                  d=|dz    d>       t=        j>                  tA        jB                  d?d@             Y nut        j                  $ r`}dA|z
  }|dBkD  rdC| dDndE}t        j                  dF| dG|        t=        j>                  tA        jB                  d?d@             Y d}~nd}~ww xY wt        j                  |       # t        j                  |       w xY w)Ha>  
        Set up the database using either prisma migrate or prisma db push
        Uses migrations from litellm-proxy-extras package

        Args:
            use_migrate: Whether to use prisma migrate instead of db push
            use_v2_resolver: Opt into the v2 migration resolver (safer during
                rolling deploys; does not run the diff-and-force recovery
                that causes schema thrashing). Defaults to False for
                backwards compatibility.

        Returns:
            bool: True if setup was successful, False otherwise
        z9Using v2 migration resolver (--use_v2_migration_resolver))r   r   r   zRunning prisma migrate deployrS   r   ry   Tr   r   zprisma migrate deploy completedzNo pending migrations to applyu>   No pending migrations — skipping post-migration sanity checkz&Running post-migration sanity check...F)r   u)   ✅ Post-migration sanity check completedzprisma db error: z, e: r   z`(\d+_.*)` migrationr   r   zS failed due to idempotent error (e.g., column already exists), resolving as appliedzFailed to roll back migration r   z+. It may already be in a rolled-back state.Nu   ✅ Migration z1 resolved, retrying to apply remaining migrationsr   zFound failed migration: z, marking as rolled backr\   rx   z" marked as rolled back... retryingr   r   a  Database schema is not empty, creating baseline migration. In read-only file system, please set an environment variable `LITELLM_MIGRATION_DIR` to a writable directory to enable migrations. Learn more - https://docs.litellm.ai/docs/proxy/prod#read-only-file-systemz4Baseline migration created, resolving all migrationsu   ✅ All migrations resolved.r   zMigration name: (\d+_.*)r   u   ❌ Migration zW failed due to insufficient permissions. Please check database user privileges. Error: z marked as rolled backz)Failed to mark migration as rolled back: z4Migration failed due to permission error. Migration zH was NOT applied. Please grant necessary database permissions and retry.z\Migration failed due to idempotent error (e.g., column already exists), resolving as appliedzRolling back migration zResolving migration z+ that failed due to existing schema objectszYP3018 error encountered but could not classify as permission or idempotent error. Error: r   r   r   )rZ   rY   zAttempt z
 timed outr   r      r   z Retrying... (z attempts left)r   z(The process failed to execute. Details: .)"r   r2   r8   r   rI   r   r   r   r   ra   rb   r6   r   rX   r   re   rf   r   r   r"   r   r~   rd   r3   r   rm   r   r`   	Exceptionr   r   r   r   r   )r   r   rJ   r   r   rn   r   rl   r   failed_migrationrollback_errr   rv   rollback_errorattempts_left	retry_msgs                   r   setup_databasez#ProxyExtrasDBManager.setup_database  s   $ KKST'::{:SS*::<?OOQx q	G99;L1AACNHH^$lKK ?@R&!+02IxH$&"&+/!% / 1" &DV]]O$TU$EF <v}}L"KK ` $(h &e $LM,DD*K% E  $OP#X &) NN,.f>RS ""
   &cq	d [ &88 u&&7zqxxj$QR"ahh..0ii 7/O  /3B3H3H3K 0#7#L#LQXX#V$*KK*45E4F  GZ  )[%&%*(<(Q(Q,<)* )3(E(E(2(A(A,& %* )/.LM]L^^`am`n oX -Y)* )*	%*%*(<(X(X,<)* )/.<=M<NN  -A)* )3(E(E(2(A(A,& %* )/.JK[J\\^_j^k,l)* )*	%* %9$P$P(6(39> %Q %& %+KK*BCSBTTl(m%& %/NN,?,A,5,5,;,<)* 13.27;-1,;,=%& %+KK*89I8JJl(m%& $qxx/ >!(( J"KK !k 1KKKX"KK V 1HH . #KK(FG#'r &s %03HHR 35))$?3"
 (7 %4$9$9!$<)2 !/ !'&4^4D EUUVU]U]T^%`!" $3
%*(<(Q(Q,:)* )/.88HH^,_)* ,5 %*(..WXfWg,h)* )*%* '3&Z[iZj kn %o'" ()!)
 "6!J!J188!T &%;!"
 35))$?3" $35D5J5J15MN%*(..EnEU,V)* )=(Q(Q,:)* )3(E(E(2(A(A,& %* )/.L^L\\^_k^l mX -Y)* )*	%*%*(..B>BR SM -N)* )=(X(X,:)* )/.<^<L MU -V)*
 )3(E(E(2(A(A,& %* )/.J>JZZ\]h\i,j)* )*	%* %9$P$P(6(39> %Q %& !''../hhZ%9!"
 !&ku&| ,, 4hw{m:>?

6++Ar2300 4 !G %q( %]O?C 
 Fqc9+VW

6++Ar2334 & &sS  ]+BG#AG#%$]#]7B+]#J98]9#LK=8]=L].L54]5#M=M83]8M==D]]B
]*.U]	V"U?:]?VA<]-X/.]/#Y8Y3.]3Y88]<A[]#\'\]\?]]]]`?A`%1`?3`%A` `? `%%`??a)T)FF)__name__
__module____qualname__staticmethodr   rI   boolrm   listru   r~   r   r   r   r   r   r   r   r    r   r   r8   r8   P   s   "S " "4 = = = =~ >S >T > > 
S 
 
$ 	
C 	
 	
 C D  4 C D  8 HLHH*-HAEH HT B B B B4 E
# E
$ E
 E
N l# l# l# l#\ ;@HH48H	H Hr   r8   )rp   r   r   r   rA   ra   r   r   pathlibr   typingr   litellm_proxy_extras._loggingr   r   r  r   dictr   compiler   r!   r$   r,   r6   r8   r  r   r   <module>r     s     	  	       0;x} ; ;	 	 2::m, 's 's '7s 7S 6` `r   