
    љi>                         S SK r S SKJr  S SKrS SKJrJrJrJrJ	r	  S SK
JrJr  S SKrSSKJrJrJrJr  SSKJr   " S S	\5      r\" \5      r " S
 S\5      rg)    N)	getLogger)AsyncGeneratorDictListProtocolType)urlparseparse_qs   )
LLMServiceLLMResponseToolCallTool)ContextManagerc                   ^    \ rS rSr% \\R                     \S'   \\R                     \S'   Sr	g)OpenAICompatibleModule
   AsyncClientAsyncAzureOpenAI N)
__name__
__module____qualname____firstlineno__r   openai_moduler   __annotations__r   __static_attributes__r       R/home/james-whalen/.local/lib/python3.13/site-packages/aiavatar/sts/llm/chatgpt.pyr   r   
   s$    m//00=99::r   r   c            )         ^  \ rS rSrSSSSSSSSSSSSSSSSSSSSS	.S
\S\S\S\S\S\S\S\S\\   S\\   S\\   S\	S\S\S\S\
S\\   S\S\S\4(U 4S jjjrS\4U 4S  jjr\S\4S! j5       rS2S"\S#\S$\S%\\\\4      S&\\\4   S\\   4S' jjrS"\S#\S(\\   S)\4S* jrS+\4S, jrS3S(\\   S-\\\4   S\\\\4      4S. jjrS2S"\S#\S(\\   S&\\\4   S/\\\\4      S\\S4   4S0 jjrS1rU =r$ )4ChatGPTService   Nz
gpt-5-minig      ?T2   Fzaiavatar.db)openai_api_keysystem_promptbase_urlmodeltemperaturereasoning_effortenable_tool_filtering
extra_bodyinitial_messagessplit_charsoption_split_charsoption_split_thresholdsplit_on_control_tagsvoice_text_taguse_dynamic_toolscontext_managershared_context_idsdb_connection_strcustom_openai_moduledebugr$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   c                |  > [         TU ]  UUUU	U
UUUUUUUUUS9  X`l        Xpl        Xl        U=(       d    [
        nSU;   aI  [        [        U5      R                  5      R                  SS /5      S   nUR                  UUUS9U l        OUR                  XS9U l        SSS	S
SSS.SSS.S.SS/S.S.S.U l        g )N)r%   r'   r(   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r7   azurezapi-versionr   )api_keyapi_versionr&   )r:   r&   functionexecute_external_toolz_Execute the most appropriate tool based on the user's intent: what they want to do and to what.objectstringzNWhat the user wants to interact with (e.g., long-term memory, weather, music).)typedescriptionzOThe type of operation to perform on the target (e.g., retrieve, look up, play).)targetactionrB   rC   )r@   
propertiesrequired)namerA   
parametersr@   r<   )super__init__r)   r*   r+   r   r
   r	   querygetr   openai_clientr   dynamic_tool_spec)selfr$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   client_moduler;   	__class__s                          r   rJ   ChatGPTService.__init__   s   0 	'#-#1#9"7)/+1/ 	 	
  !1%:"$,=e"8H#5#;#;<@@QUPVWXYZK!.!?!?&'! "@ "D "/!:!:>!:!eD /  A$ %-+{#
 %-+|#	# "*8 4"
r   returnc                 ~   > [         TU ]  5       nU R                  US'   U R                  US'   U R                  US'   U$ )Nr)   r*   r+   )rI   
get_configr)   r*   r+   )rO   configrQ   s     r   rU   ChatGPTService.get_config_   sE    #%%)%:%:!"*.*D*D&'#|r   c                 &    U R                   S   S   $ )Nr<   rF   )rN   )rO   s    r   dynamic_tool_name ChatGPTService.dynamic_tool_namef   s    %%j1&99r   
context_iduser_idtextfilessystem_prompt_paramsc                   #    / nU R                  XU5      I S h  vN =n(       a  UR                  SUS.5        U R                  (       a  UR                  U R                  5        U R                  R                  U R                  (       a  U/U R                  -   OUS9I S h  vN nU(       a2  US   S   S:w  a&  UR                  S5        U(       a  US   S   S:w  a  M&  UR                  U5        U(       aW  / n	U H3  n
U
R                  S5      =n(       d  M  U	R                  SSU0S	.5        M5     U(       a  U	R                  S
US.5        OUn	UR                  SU	S.5        U$  GNN N7f)Nsystemrolecontent)r[   r   rc   userurl	image_url)r@   rg   r]   r@   r]   )	_get_system_promptappendr,   extendr3   get_historiesr4   poprL   )rO   r[   r\   r]   r^   r_   messagesr%   	historiesrd   frf   s               r   compose_messagesChatGPTService.compose_messagesj   sJ    "&"9"9*Oc"ddd=dOOX-HI   OOD112 ..<<AEAXAX
|d&=&==^h = 
 
	 IaL0F:MM! IaL0F:	"G%%,&3&NNKucl#ST  =>GG<=5 e
s/   E-E(BE-#E+$;E-!5E-AE-+E-rn   response_textc                   #    U R                   (       a  [        US   S   [        5      (       a9  SUS   S   S   ;   a)  U R                  US   S   S   S   5      US   S   S   S'   O8[        US   S   [        5      (       a  U R                  US   S   5      US   S'   UR	                  SUS.5        U R
                  R                  XS5      I S h  vN   g  N7f)Nr   rd   r]   	assistantrb   chatgpt)_update_context_filter
isinstanceliststrrj   r3   add_histories)rO   r[   r\   rn   rs   s        r   update_contextChatGPTService.update_context   s     &&(1+i0$77Xa[3B779=9T9TU]^_U`ajUklnUopvUw9xHQK	*2.v6HQK	2C88)-)D)DXa[QZE[)\I&GH""00yQQQs   CCCCspecc                    ^ ^ U U4S jnU$ )Nc                 H   > TS   S   n[        UTU S9TR                  U'   U $ )Nr<   rF   )rF   r   func)r   tools)r   	tool_namerO   r   s     r   	decorator&ChatGPTService.tool.<locals>.decorator   s5    Z(0I$(%DJJy!
 Kr   r   )rO   r   r   s   `` r   toolChatGPTService.tool   s    	 r   metadatac                   #    U R                   nU R                  R                  5        H+  u  pEUSUR                   SUR                  S   S    S3-  nM-     US-  nUS   S   n[        U[        5      (       aj  / nS	nU HD  n	U	S
   n
U
S:X  a%  U(       d  UR                  SU	S   U-   S.5        SnM3  UR                  U	5        MF     U(       d  UR                  SUS.5        O[        U[        5      (       a  Xc-   nSU R                  0n[        U5      S:  a  US   S   S:X  a  USWS./-   US'   OUS S SWS./-   US'   U R                  (       a  U R                  US'   O[U R                  R                  S5      (       a  SUS'   O5U R                  R                  S5      (       a  SUS'   OU R                  US'   U R                  (       a  U R                  US'   U R                  (       a  [         R#                  SU 35        U R$                  R&                  R(                  R*                  " S!0 UD6I S h  vN n[,        R.                  " SUR0                  S   R2                  R4                  5      =n(       a  UR7                  S5      nOSn/ nUR9                  S 5       HP  nU R                  R;                  UR=                  5       5      =n(       d  M5  UR                  UR                  5        MR     U$  N7f)"Nz- z: r<   rA   
z6- NOT_FOUND: Use this if no suitable tools are found.
ru   rd   Fr@   r]   rh   Tr'   r   rc   r   re   rb   rn   r)   gpt-5.1nonegpt-5minimalr(   r+   z)Request to ChatGPT to get dynamic tools: z\[tools:(.*?)\]r   	NOT_FOUND,r   )"additional_prompt_for_tool_listingr   itemsrF   r   ry   rz   rj   r{   r'   lenr)   
startswithr(   r+   r7   loggerinforM   chatcompletionscreateresearchchoicesmessagerd   groupsplitrL   strip)rO   rn   r   tool_listing_prompt_tuser_contentuser_content_for_tooltext_updatedccontent_typechat_completion_paramstool_choice_respmatch
tool_namesr   r   s                    r   get_dynamic_tools_default(ChatGPTService.get_dynamic_tools_default   s    "EEJJ$$&DARxr!&&2D]2S1TTV#WW 'XX  |I.lD))$&! L! y6),)00&!F)ViJi1jk#'L *003 "  %,,fFY-Z[c**$0$F! TZZ"
 x=1"f!5!?19fYn=o<p1p":.19#26^sBtAu1u":.  9=9N9N"#56ZZ""9--9?"#56ZZ""7++9B"#56484D4D"=1??37??"<0::KKCDZC[\]!%!3!3!8!8!D!D!K!K!eNd!ee II02B2J2J12M2U2U2]2]^^5^QJ$J!!#&Azz~~aggi00t0TYY' '  fs   H8K=:K;;BK="K=r   c           	       ^ #    T R                   R                  5        VVs/ s H  u  pgUR                  PM     nnnT R                  (       a  UR	                  T R
                  5        U(       a  U Vs/ s H  nSSUS   S   0S.PM     n	nOT R                  (       a  SST R                  0S./n	O|T R                   R                  5        VVs/ s H$  u  pgUR                  (       a  M  UR                  PM&     snn=(       d    S n
U
(       a  U
 Vs/ s H  nSSUS   S   0S.PM     snOS n	UT R                  SS.nT R                  (       a  T R                  US'   O[T R                  R                  S5      (       a  SUS'   O5T R                  R                  S	5      (       a  S
US'   OT R                  US'   T R                  (       a  T R                  US'   U(       aH  XS'   [        U 4S jS 5       5      (       a  O)T R                  (       a  U	(       a  SSU	S.S.US'   OSUS'   T R                  (       a  [         R#                  SU 35         T R$                  R&                  R(                  R*                  " S.0 UD6I S h  vN n/ nSn/ nU  S h  vN nUR:                  (       a  UR:                  S   R<                  (       d  M:  UR:                  S   R<                  R>                  (       Ga*  UR:                  S   R<                  R>                  S   nUR@                  (       a  UR	                  [C        UR@                  URD                  RF                  S5      5        URD                  RF                  T R                  :X  aH  [         R#                  S5        T RI                  U5      I S h  vN n[         R#                  SU 35        SnURD                  RJ                  (       a/  US   =RJ                  URD                  RJ                  -  sl%        GM  GM  UR:                  S   R<                  RL                  =n(       d  GM  U(       a  GM  [7        UUS 97v   GM  s  snnf s  snf s  snnf s  snf  GN! [,        R.                   aV  nS n UR0                  R3                  5       nO!    O= f[         R5                  SU 35        [7        XUS.S97v    S nAg S nAf[8         a1  n[         R5                  SU 35        [7        XS S.S97v    S nAg S nAff = f GN GNu
 U(       Ga  T RO                  U5      I S h  vN    [Q        U5      nU GH  nT R                  (       a"  [         R#                  S!URF                   35        [7        UUS"97v   S nURF                  T R                  :X  a  U(       d  S#S$0nOT RS                  URF                  [2        RT                  " URJ                  5      S%U05        S h  vN  nUUl+        URX                  (       a  [7        UURX                  S 97v   M;  [7        UUS"97v   URZ                  (       d  M[  UR\                  n  O
 T R                  (       a  [         R#                  S&U 35        U(       d  GMF  UR	                  S'UR@                  SURF                  URJ                  S(.S)./S*.5        UR	                  S+[2        R^                  " U5      UR@                  S,.5        GM     [Q        U5      U:  d  U(       a$  T Ra                  XX4US-9  S h  vN  nU7v   M  
 g g g 7f)/Nr<   rF   rH   T)rn   r'   streamr)   r   r   r   r   r(   r+   r   c              3   @   >#    U  H  oTR                   ;   v   M     g 7fN)r'   ).0mrO   s     r   	<genexpr>9ChatGPTService.get_llm_stream_response.<locals>.<genexpr>  s     I,Hq

?,Hs   )grokgeminiclaudeallowed_toolsauto)moder   )r@   r   tool_choicezRequest to ChatGPT: zAPIStatusError from OpenAI: )	exceptionresponse_json)r[   
error_infozError from OpenAI: Fr    zGet dynamic toolzDynamic tools: ru   )r[   r]   z
ToolCall: )r[   	tool_callr   zNo tools foundr\   zToolCall result: rv   )rF   	arguments)idr@   r<   )rc   
tool_callsr   )rc   rd   tool_call_id)r_   r   r   )1r   r   r   r2   rj   rN   rY   
is_dynamicr'   r)   r   r(   r+   anyr*   r7   r   r   rM   r   r   r   r   APIStatusErrorresponsejsonwarningr   	Exceptionr   deltar   r   r   r<   rF   _get_dynamic_toolsr   rd   _on_before_tool_callsr   execute_toolloadsresultr]   is_finaldatadumpsget_llm_stream_response)rO   r[   r\   rn   r_   r   r   r   	all_toolsr   non_dynamic_toolsr   stream_respaserrr   exr   try_dynamic_toolsfiltered_toolschunkrd   messages_lengthtctool_resulttrllm_responses   `                         r   r   &ChatGPTService.get_llm_stream_response   sE    (,

(8(8(:;(:QVV(:	;!!T334 hmnhmcdjvq}U[G\>]^hmMnM##&0vtG]G]>^_`M 59JJ4D4D4F [4FDAall4F [ c_c Phyzhycdjvq}U[G\>]^hyz  VZM !ZZ"
   9=9N9N"#56ZZ""9--9?"#56ZZ""7++9B"#56484D4D"=1??37??"<0 .77+I,HIII++ ETpv  BO  hP  =Q*=9<B*=9::KK./E.FGH	 $ 2 2 7 7 C C J J dMc ddK" &(
!& 	K%==a(8(>(>}}Q%%000MM!$**55a844%%hqttQZZ__b&IJzz$*@*@@$67/3/F/Fx/P)Pon5E$FG,0)::''rN,,

0D0DD,, ( "MM!,22:::::((%'JJw < o !\zN e++ 	 M % 3 3 5NN9%ABfs@tuu 	NN056cg@hii		K *Q '( ,,Z888 "(mO ::KK*RWWI 67!Z2FF"77d444)'02B&C$($5$5bggtzz",,?WZcelYm$n & &b$&	77"-"''"RR"-r"RR!{{{.0gg % %o ::KK"3K= AB;OO +"$%%$.(*-/\\)( '
% 
 OO &#'::k#:(*% I !T 8}.2C*.*F*Fdr +G + ' ', '&+ 3Da s0  ]Q&:]3Q,
A]Q1)Q19]Q7(D)]3Q? Q<Q? 
]T+T%T+D]3T(4B]]&]<Q? ?T"S$R10S$1R53,S$]$T"1'T]T""]%T+(]+]U	B;]Y-X	Y-A]=]!B]:]>]?]])rN   r*   r+   rM   r)   )NNr   )r   r   r   r   r{   floatbooldictr   intr   r   rJ   rU   propertyrY   r   r   rq   r}   r   r   r   r   r   r   __classcell__)rQ   s   @r   r!   r!      s    #!!  $&*'+!%(,&(&*""'*.(,!.7;-K
 K
 	K

 K
 K
 K
 K
  $K
 K
 t*K
 #YK
 !IK
 !$K
  $K
  !K
"  #K
$ (%K
& !I'K
( )K
* 5+K
, -K
 K
ZD  :3 : : s # VZ[_`ceh`h[iVj   JN  OR  TW  OW  JX   dh  im  dn <Rs RS RDQUJ Rgj R	 	@T
 @dSVX[S[n @hlmqruwzrzm{h| @DT' T'c T'UYZ^U_ T'w{|  BE  }E  xF T'  VZ  [_  `c  eh  `h  [i  Vj T'  vD  EP  RV  EV  vW T' T'r   r!   )r   loggingr   r   typingr   r   r   r   r   urllib.parser	   r
   openair   r   r   r   r   r   r3   r   r   r   r   r!   r   r   r   <module>r      sI      	 = = +  5 5 +;X ; 
8	b'Z b'r   