
    R"h                     N   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	m
Z
mZ d dlZd dlmZ d dlmZmZmZ d dlmZ d dlmZ d dlmZmZ d dlmZ 	 d d	lmZ d dlZ ej@                         5   ejB                  d
e"       dejF                  vrdejF                  d<   d dl$Z$de$_%        de$_&        ddd       d dl'm(Z( ejR                  jU                   ejV                         d      Z, e(e,d      e$_-        dZ. G d d      Z/ ej`                  e.      d        Z1dddfdZ2 ej`                  e.      d        Z3dddfdZ4d9de5de5fdZ6d9de5de5fd Z7d:d!e8fd"Z9 G d# d$e/      Z: G d% d&ej0                        Z; G d' d(ej0                        Z< G d) d*ej^                        Z= G d+ d,ej0                        Z> G d- d.ej                  j~                  j                  j^                        ZA G d/ d0ej                  j^                        ZB G d1 d2ej                        ZD G d3 d4ej                        ZF G d5 d6ej                        ZH G d7 d8ej                  j~                  j                  j^                        ZIy# e$ r dZY 6w xY w# 1 sw Y   xY w);    N)OptionalLiteralAny)Path)ERRORSbackoff_hdlrgiveup_hdlr)openai_to_hf)send_hftgi_request_v01_wrapped)OpenAIAzureOpenAI)AutoTokenizer)RateLimitErrorignore)categoryLITELLM_LOCAL_MODEL_COST_MAPTrueTF)Cachez.storm_local_cachedisk)disk_cache_dirtypei  c                   2    e Zd Z	 	 	 	 ddZddZddefdZy)	LMc                     || _         || _        || _        t        d||d|| _        g | _        d|v r|dk\  r|dk(  sJ d       y y )N)temperature
max_tokenszo1-i        ?z]OpenAI's o1-* models require passing temperature=1.0 and max_tokens >= 5000 to `dspy.LM(...)` )model
model_typecachedictkwargshistory)selfr   r    r   r   r!   r#   s          3/var/www/html/sandstorm/storm/knowledge_storm/lm.py__init__zLM.__init__:   sf     
$
T{zTVTE>d"{c'9ono9'9     Nc           
         |j                  d| j                        }|xs d|dg}i | j                  |}| j                  dk(  r|rt        nt
        }n|rt        nt        } |t        j                  t        d| j                  |d|            }|d   D cg c])  }t        |d      r|j                  j                  n|d   + }}|j                         D 	
ci c]  \  }	}
|	j!                  d	      r|	|
 }}	}
t        ||||
      }t        di ||t        |d         d}t        di |d|j#                  di       j#                  d      i}| j$                  j'                  |       |S c c}w c c}
}	w Nr!   userrolecontentchatr   messageschoicesmessagetextapi_)promptr1   r#   responseusage)outputsr8   cost_hidden_paramsresponse_costr   )popr!   r#   r    cached_litellm_completionlitellm_completioncached_litellm_text_completionlitellm_text_completionujsondumpsr"   r   hasattrr3   r.   items
startswithgetr$   append)r%   r6   r1   r#   r!   
completionr7   cr9   kventrys               r&   __call__zLM.__call__N   s   

7DJJ/DF CD*DKK*6* ??f$6;2ASJ 38.=T  KKK4::KFKL

 i(
 ")I!6AIIAfIE
 
 $*<<>N41af9M!Q$NNFXfxXMuMgT(7:K5LM 

",,'7<@@Q
 	E"
 Os   .E6E;8E;nc                     t        | |       y N)_inspect_history)r%   rO   s     r&   inspect_historyzLM.inspect_historyo   s    q!r(   )r/             TNN   )__name__
__module____qualname__r'   rN   intrS   r   r(   r&   r   r   9   s(     o(B" "r(   r   )maxsizec                 "    t        | ddd      S NFzno-cachezno-store)r!   )r?   requests    r&   r>   r>   s   s    g%U-STTr(   r`   c                 Z    t        j                  |       }t        j                  dd|i|S )Nr!   r   )rB   loadslitellmrI   )rb   r!   r#   s      r&   r?   r?   x   s)    [[!F4E4V44r(   c                 "    t        | ddd      S r_   )rA   ra   s    r&   r@   r@   }   s    "Eu= r(   c           	         t        j                  |       }|j                  d      j                  dd      }t	        |      dkD  r|d   nd|d   }}|j                  dd       xs t        j                  | d      }|j                  d	d       xs t        j                  | d
      }dj                  |j                  d      D cg c]  }|d   	 c}dgz         }t        j                  d|d| |||d|S c c}w )Nr   /rX   r   openaiapi_key_API_KEYapi_base	_API_BASEz

r1   r.   zBEGIN RESPONSE:ztext-completion-openai/)r!   r   rk   rm   r6   r   )
rB   rd   r=   splitlenosgetenvjoinre   text_completion)	rb   r!   r#   r   providerrk   rm   xr6   s	            r&   rA   rA      s	   [[!F JJw%%c1-E"%e*q.eAhhb	eH jjD)MRYY(87L-MGzz*d+PryyH:Y9O/PH [[%zz*56!96:K9LLF "" 'w/   	7s   C<r4   endc                 F    dt        |       j                         z   dz   |z   S )Nz[32m[0m)strlstripr4   rw   s     r&   _greenr}      s$    D	((**Y6<<r(   c                 *    dt        |       z   dz   |z   S )Nz[31mry   )rz   r|   s     r&   _redr      s    D	!I-33r(   rO   c                    | j                   | d D ]  }|d   xs	 d|d   dg}|d   }t        d       |D ]Q  }t        t        |d   j                          d	             t        |d
   j	                                t        d       S t        t        d             t        t        |d   j	                                      t        |      dkD  sdt        |      dz
   d}t        t        |d              t        d       y)z0Prints the last n prompts and their completions.Nr1   r+   r6   r,   r9   z


r-   z	 message:r.   
z	Response:r   rX   z 	 (and z other completions) )rw   )r$   printr   
capitalizestripr}   rp   )lmrO   itemr1   r9   msgchoices_texts          r&   rR   rR      s     

A23 .
#TDN(S'Ty/h 	C$#f+00239=>?#i.&&()$K	
 	d; fWQZ%%'()w<!&s7|A~&66IJL$|,-." 
(Or(   c                   X     e Zd ZdZ	 	 	 d
dedee   ded   f fdZd Zd Z	dd	Z
 xZS )LitellmModelzjA wrapper class for LiteLLM.

    Check out https://docs.litellm.ai/docs/providers for usage details.
    r   rk   r    r/   r4   c                 z    t        |   d|||d| t        j                         | _        d| _        d| _        y N)r   rk   r    r   r   superr'   	threadingLock_token_usage_lockprompt_tokenscompletion_tokensr%   r   rk   r    r#   	__class__s        r&   r'   zLitellmModel.__init__   >     	Wug*WPVW!*!1!"r(   c                    |j                  d      }|r`| j                  5  | xj                  |j                  dd      z  c_        | xj                  |j                  dd      z  c_        ddd       yy# 1 sw Y   yxY wz2Log the total tokens from the OpenAI API response.r8   r   r   r   NrG   r   r   r   r%   r7   
usage_datas      r&   	log_usagezLitellmModel.log_usage   y    \\'*
'' Q""jnn_a&HH"&&*..9La*PP&Q Q Q Q   AA55A>c                     | j                   xs8 | j                  j                  d      xs | j                  j                  d      | j                  | j                  di}d| _        d| _        |S 4Get the total tokens used and reset the token usage.r   enginer   r   r   )r   r#   rG   r   r   r%   r8   s     r&   get_usage_and_resetz LitellmModel.get_usage_and_reset   sj     JJ ){{w'){{x(!%!3!3%)%;%;+
 !"r(   c           
      D   |j                  d| j                        }|xs d|dg}i | j                  |}| j                  dk(  r|rt        nt
        }n|rt        nt        } |t        j                  t        d| j                  |d|            }|j                         }| j                  |       |d   D cg c])  }t        |d      r|j                  j                   n|d   + }	}|j#                         D 
ci c]  \  }
}|
j%                  d	      r|
| }}
}t        ||||
      }t        di ||	t        |d         d}t        di |d|j'                  di       j'                  d      i}| j(                  j+                  |       |	S c c}w c c}}
w r*   )r=   r!   r#   r    r>   r?   r@   rA   rB   rC   r"   r   jsonr   rD   r3   r.   rE   rF   rG   r$   rH   )r%   r6   r1   r#   r!   rI   r7   response_dictrJ   r9   rK   rL   rM   s                r&   rN   zLitellmModel.__call__   s   

7DJJ/DF CD*DKK*6* ??f$6;2ASJ 38.=T  KKK4::KFKL
 !}% i(
 ")I!6AIIAfIE
 
 $*<<>N41af9M!Q$NNHVm
 RuRgT-:P5QR 

",,'7<@@Q
 	E"!
 Os   <.F?FF)zopenai/gpt-4o-miniNr/   rV   )rY   rZ   r[   __doc__rz   r   r   r'   r   r   rN   __classcell__r   s   @r&   r   r      sM     *!%.4	
#
# #
# N+	
#Q#r(   r   c                   ~     e Zd ZdZ	 	 	 ddedee   ded   f fdZd Zd Z		 	 dd	ed
e
de
deeeef      fdZ xZS )OpenAIModelz A wrapper class for dspy.OpenAI.r   rk   r    r   c                 z    t        |   d|||d| t        j                         | _        d| _        d| _        y r   r   r   s        r&   r'   zOpenAIModel.__init__  r   r(   c                    |j                  d      }|r`| j                  5  | xj                  |j                  dd      z  c_        | xj                  |j                  dd      z  c_        ddd       yy# 1 sw Y   yxY wr   r   r   s      r&   r   zOpenAIModel.log_usage#  r   r   c                     | j                   j                  d      xs | j                   j                  d      | j                  | j                  di}d| _        d| _        |S r   r#   rG   r   r   r   s     r&   r   zOpenAIModel.get_usage_and_reset+  ^     KKOOG$ ){{x(!%!3!3%)%;%;+
 !"r(   r6   only_completedreturn_sortedreturnc                    |sJ d       |du sJ d        | j                   |fi |}| j                  |       |d   }|D cg c]  }|d   dk7  s| }}|rt        |      r|}|D cg c]  }| j                  |       }	}|r|j	                  dd      dkD  rg }
|D ]m  }|d   d	   |d   d
   }}d|v r|j                  d      dz   }|d| |d| }}t        |      t        |      z  }|
j                  || j                  |      f       o t        |
d      }
|
D cg c]  \  }}|	 }	}}|	S c c}w c c}w c c}}w )zOCopied from dspy/dsp/modules/gpt3.py with the addition of tracking token usage.for nowFr2   finish_reasonlengthrO   rX   logprobstokenstoken_logprobsz<|endoftext|>NT)reverse)	rb   r   rp   _get_choice_textrG   indexsumrH   sorted)r%   r6   r   r   r#   r7   r2   rJ   completed_choicescompletionsscored_completionsr   r   r   avglog_s                   r&   rN   zOpenAIModel.__call__9  s    (y(~%0y0%  4<<1&1 	x 9%(/R11_3E3QQRRc"34'G9@AAt,,Q/AAVZZQ/!3!# NjM(+jM"23 !
 #f,"LL9A=E'-fu~x7GHFXX6"))643H3H3K*LMN "((:D!I);<A1<K<3 S
 B$ =s   D1D1)D6 D;)zgpt-4o-miniNNTF)rY   rZ   r[   r   rz   r   r   r'   r   r   boollistr"   r   rN   r   r   s   @r&   r   r     s    * #!%.2	
#
# #
# N+	
#Q"  $#	22 2 	2 
d38n	2r(   r   c                        e Zd ZdZ	 	 	 ddedee   def fdZd Zd Z e	j                  e	j                  edee	      d
efd       Z	 	 dd
edededeeeef      fdZ xZS )DeepSeekModelz>A wrapper class for DeepSeek API, compatible with dspy.OpenAI.r   rk   rm   c                     t        |   d|||d| t        j                         | _        d| _        d| _        || _        |xs t        j                  d      | _
        || _        | j                  st        d      y )Nr   rk   rm   r   DEEPSEEK_API_KEYzfDeepSeek API key must be provided either as an argument or as an environment variable DEEPSEEK_API_KEYr   r   r'   r   r   r   r   r   r   rq   rr   rk   rm   
ValueErrorr%   r   rk   rm   r#   r   s        r&   r'   zDeepSeekModel.__init__q  s}     	SugSFS!*!1!"
?")),>"? ||x  r(   c                    |j                  d      }|r`| j                  5  | xj                  |j                  dd      z  c_        | xj                  |j                  dd      z  c_        ddd       yy# 1 sw Y   yxY w)z4Log the total tokens from the DeepSeek API response.r8   r   r   r   Nr   r   s      r&   r   zDeepSeekModel.log_usage  r   r   c                 l    | j                   | j                  | j                  di}d| _        d| _        |S r   r   r   r   r   r   r   s     r&   r   z!DeepSeekModel.get_usage_and_reset  @     JJ!%!3!3%)%;%;
 !"r(   rU   max_time
on_backoffgiveupr6   c                     dd| j                    d}| j                  d|dgd|}t        j                  | j                   d||      }|j                          |j                         S )	z+Create a completion using the DeepSeek API.application/jsonBearer zContent-TypeAuthorizationr+   r,   r0   z/v1/chat/completionsheadersr   )rk   r   requestspostrm   raise_for_statusr   )r%   r6   r#   r   datar7   s         r&   _create_completionz DeepSeekModel._create_completion  s~     /&t||n5

 ZZ"(V<=
 

 ==}}o12G$
 	!!#}}r(   r   r   r   c                     |sJ d       |du sJ d        | j                   |fi |}| j                  |       |d   }|D cg c]
  }|d   d    }}|||d}	| j                  j                  |	       |S c c}w )z.Call the DeepSeek API to generate completions.r   Fr2   r3   r.   r6   r7   r#   r   r   r$   rH   
r%   r6   r   r   r#   r7   r2   choicer   r$   s
             r&   rN   zDeepSeekModel.__call__       (y(~%0y0%*4**6<V< 	x 9%BIJvi(3JJ  

 	G$ K   A6)zdeepseek-chatNzhttps://api.deepseek.comr   rY   rZ   r[   r   rz   r   r'   r   r   backoffon_exceptionexpor   r   r	   r   r   r   r"   r   rN   r   r   s   @r&   r   r   n  s    H %!%2	 # 	&Q
 W (  $#	  	 
d38n	r(   r   c                        e Zd ZdZ	 ddededededed   f
 fdZ ej                  ej                  e
d	ee
      dedefd       ZdedefdZd Zd Z	 	 ddedededee   fdZ xZS )AzureOpenAIModelz}A wrapper class of Azure OpenAI endpoint.

    Note: param::model should match the deployment_id on your Azure platform.
    azure_endpointapi_versionr   rk   r    r   c                    t         |   |       t        j                         | _        d| _        d| _        || _        d| _        || _	        t        |||      | _        d| _        d| _        |ddddddd|| _        y )	Nr   r   azure)r   rk   r   rT      rX   )r   r   r   top_pfrequency_penaltypresence_penaltyrO   )r   r'   r   r   r   r   r   r   ru   r    r   clientr#   )r%   r   r   r   rk   r    r#   r   s          r&   r'   zAzureOpenAIModel.__init__  s     	u%!*!1!"
$!)#

 !" !" !	
 	
r(   rU   r   r6   r   c                    i | j                   |}	 | j                  dk(  r9d|dg} | j                  j                  j                  j
                  dd|i|}n( | j                  j                  j
                  dd|i|}| j                  |       |t        |      |d}| j                  j                  |       |S # t        $ r'}t        j                  dt        |               d }~ww xY w)	Nr/   r+   r,   r1   r6   r   z&Error making request to Azure OpenAI: r   )r#   r    r   r/   r   creater   r"   r$   rH   	Exceptionloggingerrorrz   )r%   r6   r#   r1   r7   history_entryes          r&   basic_requestzAzureOpenAIModel.basic_request  s     +DKK*6*	&(%+?@>4;;++77>> %)/ :4;;2299RR6RNN8$ ! N M
 LL.O 	MMB3q6(KL	s   B,B? ?	C/"C**C/r   c                 d    | j                   dk(  r|j                  j                  S |j                  S )z6Extract text from a choice object based on model type.r/   )r    r3   r.   r4   )r%   r   s     r&   r   z!AzureOpenAIModel._get_choice_text  s(    ??f$>>))){{r(   c                     |j                   }|rT| j                  5  | xj                  |j                  z  c_        | xj                  |j                  z  c_        ddd       yy# 1 sw Y   yxY w)z#Log the total tokens from response.Nr8   r   r   r   r   s      r&   r   zAzureOpenAIModel.log_usage   i    ^^
'' G""j&>&>>"&&**F*FF&G G G G   ?A$$A-c                 l    | j                   | j                  | j                  di}d| _        d| _        |S r   r   r   s     r&   r   z$AzureOpenAIModel.get_usage_and_reset(  r   r(   r   r   c                      | j                   |fi |}|j                  }|D cg c]  }|j                  dk7  s| }}|r|r|}|D cg c]  }| j                  |       }	}|	S c c}w c c}w )an  Get completions from Azure OpenAI.

        Args:
            prompt: The prompt to send to the model
            only_completed: Only return completed responses
            return_sorted: Sort completions by probability (not implemented)
            **kwargs: Additional arguments to pass to the API

        Returns:
            List of completion strings
        r   )r  r2   r   r   )
r%   r6   r   r   r#   r7   r2   rJ   r   r   s
             r&   rN   zAzureOpenAIModel.__call__4  s    $ &4%%f77""(/O11??h3NQOO/'G9@AAt,,Q/AA P
 Bs   A%A%	A*)r/   r   )rY   rZ   r[   r   rz   r   r'   r   r   r   r   r   r	   r   r  r   r   r   r   r   rN   r   r   s   @r&   r   r     s     /5"
"
 "
 	"

 "
 N+"
H WC c 8s s G
  $#	  	 
cr(   r   c                        e Zd ZdZ	 	 	 ddedee   def fdZd Zd Z e	j                  e	j                  edee	      d
efd       Z	 	 dd
edededeeeef      fdZ xZS )	GroqModelzVA wrapper class for Groq API (https://console.groq.com/), compatible with dspy.OpenAI.r   rk   rm   c                     t        |   d|||d| t        j                         | _        d| _        d| _        || _        |xs t        j                  d      | _
        || _        | j                  st        d      y )Nr   r   GROQ_API_KEYz^Groq API key must be provided either as an argument or as an environment variable GROQ_API_KEYr   r   r   s        r&   r'   zGroqModel.__init__V  s|     	SugSFS!*!1!"
;"))N"; ||p  r(   c                    |j                  d      }|r`| j                  5  | xj                  |j                  dd      z  c_        | xj                  |j                  dd      z  c_        ddd       yy# 1 sw Y   yxY w)z0Log the total tokens from the Groq API response.r8   r   r   r   Nr   r   s      r&   r   zGroqModel.log_usagei  r   r   c                 l    | j                   | j                  | j                  di}d| _        d| _        |S r   r   r   s     r&   r   zGroqModel.get_usage_and_resetq  r   r(   rU   r   r6   c                    dd| j                    d}|j                  dd       |j                  dd       |j                  dd       d|v r|d   d	k7  rt        d
      |j                  dd	      dk(  rd|d<   | j                  d|dgd|}|d   D ]  }|j                  dd        t        j                  | j                   d||      }|j                          |j                         S )z'Create a completion using the Groq API.r   r   r   r   N
logit_biastop_logprobsrO   rX   zGroq API only supports N=1r   r   g:0yE>r+   r,   r0   r1   namez/chat/completionsr   )
rk   r=   r   rG   r   r   r   rm   r   r   )r%   r6   r#   r   r   r3   r7   s          r&   r   zGroqModel._create_completion}  s    /&t||n5
 	

:t$

<&

>4( &=VC[A-9:: ::mQ'1,$(F=! ZZ"(V<=
 
 J' 	&GKK%	& ==}}o./t
 	!!#}}r(   r   r   r   c                     |sJ d       |du sJ d        | j                   |fi |}| j                  |       |d   }|D cg c]
  }|d   d    }}|||d}	| j                  j                  |	       |S c c}w )z*Call the Groq API to generate completions.r   Fr2   r3   r.   r   r   r   s
             r&   rN   zGroqModel.__call__  r   r   )zllama3-70b-8192Nzhttps://api.groq.com/openai/v1r   r   r   s   @r&   r  r  S  s    ` '!%8	 # 	&Q
 W" ""N  $#	  	 
d38n	r(   r  c                        e Zd ZdZ	 	 ddedee   dee   f fdZd Zd Zdefd	Z	 e
j                  e
j                  efd
dee      defd       ZddZ xZS )ClaudeModelzTCopied from dspy/dsp/modules/anthropic.py with the addition of tracking token usage.r   rk   rm   c                 d   t         |   |       	 ddlm} d| _        |t        j                  j                  d      n|x| _	        }|dn|| _
        |j                  dd      t        |j                  d	d
      d
      |j                  dd      |j                  dd      |j                  d|j                  dd            d|d|i| _        g | _         ||      | _        || _        t#        j$                         | _        d| _        d| _        y # t        $ r}t	        d      |d }~ww xY w)Nr   )	Anthropicz(Claude requires `pip install anthropic`.	anthropicANTHROPIC_API_KEYz%https://api.anthropic.com/v1/messagesr   rT   r      r   r   top_krX   rO   num_generations)r   r   r   r!  rO   r   rk   )r   r'   r  r  ImportErrorru   rq   environrG   rk   rm   minr=   r#   r$   r   r   r   r   r   r   r   )r%   r   rk   rm   r#   r  errr   s          r&   r'   zClaudeModel.__init__  s2    		S+ $3:?BJJNN./	
w 8@7G3X 	 "::mS9fjjt<dCZZ-ZZ+C,=q!AB
 
 U
 .00
!*!1!"3  	SHIsR	Ss   D 	D/D**D/c                     |j                   }|rT| j                  5  | xj                  |j                  z  c_        | xj                  |j
                  z  c_        ddd       yy# 1 sw Y   yxY w)z5Log the total tokens from the Anthropic API response.N)r8   r   r   input_tokensr   output_tokensr   s      r&   r   zClaudeModel.log_usage  si    ^^
'' C""j&=&=="&&**B*BB&C C C Cr  c                 l    | j                   | j                  | j                  di}d| _        d| _        |S r   r   r   s     r&   r   zClaudeModel.get_usage_and_reset  @     JJ!%!3!3%)%;%;
 !"r(   r6   c           
         |}i | j                   |}d|dg|d<   |j                  d        | j                  j                  j                  d	i |}||j
                  d   j                  |j                  |j                  |j                  |j                  |j                  |j                  j                  |j                  j                  dd||d}| j                  j!                  |       |S )
Nr+   r,   r1   rO   r   )r)  r*  )r.   r   r-   stop_reasonstop_sequencer   r8   r6   r7   r#   
raw_kwargsr   )r#   r=   r   r1   r  r.   r4   r   r-   r.  r/  r   r8   r)  r*  r$   rH   )r%   r6   r#   r1  r7   json_serializable_historys         r&   r  zClaudeModel.basic_request  s    
*DKK*6*'-&ABz

3.4;;''..88 #++A.33! '33!)!7!7 $,NN$?$?%-^^%A%A $%
!" 	56r(   rU      r   	max_triesr   r   c                 (     | j                   |fi |S )zKHandles retrieval of completions from Anthropic whilst handling API errors.r  r%   r6   r#   s      r&   rb   zClaudeModel.request#       "t!!&3F33r(   c                    |sJ d       |du sJ d       |j                  dd      }g }t        |      D ]I  } | j                  |fi |}| j                  |       |j                  D 	cg c]  }	|	j
                   }}	K |S c c}	w )a  Retrieves completions from Anthropic.

        Args:
            prompt (str): prompt to send to Anthropic
            only_completed (bool, optional): return only completed responses and ignores completion due to length. Defaults to True.
            return_sorted (bool, optional): sort the completion choices using the returned probabilities. Defaults to False.

        Returns:
            list[str]: list of completion choices
        r   FrO   rX   )r=   rangerb   r   r.   r4   )
r%   r6   r   r   r#   rO   r   r   r7   rJ   s
             r&   rN   zClaudeModel.__call__/  s     (y(~%0y0% JJsAq 	=A#t||F5f5HNN8$ ,4+;+;<a166<K<	=  =s   )BrV   r   )rY   rZ   r[   r   rz   r   r'   r   r   r  r   r   r   r   r   r	   rb   rN   r   r   s   @r&   r  r    s    ^
 "&"&	#### ### 3-	##JCC B W	4c 44r(   r  c                        e Zd ZdZ	 	 	 dded   f fdZd Z ej                  ej                  e
de      defd	       Zd
 Zd ZdefdZ xZS )
VLLMClientzA client compatible with vLLM HTTP server.

    vLLM HTTP server is designed to be compatible with the OpenAI API. Use OpenAI client to interact with the server.
    r    r   c                 2   t         |   |       i | j                  || _        || _        | d| d| _        |dk(  r| xj                  dz  c_        t        | j                  |      | _        d| _        d| _        t        j                         | _        y)	zdCheck out https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html for more information.r   :z/v1/r/   zchat/)base_urlrk   r   N)r   r'   r#   r   r@  r   r   r   r   r   r   r   )r%   r   portr    urlrk   r#   r   s          r&   r'   zVLLMClient.__init__S  s     	u%///
%qd+MMW$MdmmWE!"!*!1r(   c                 v     | j                   j                  j                  j                  di |dd|dgi}|S )Nr1   r+   r,   r   )r   r/   r   r  )r%   r6   r#   rI   s       r&   r  zVLLMClient.basic_requesti  sD    8T[[%%1188 

%&9:

 r(   rU   r   r   r6   c                 (     | j                   |fi |S rQ   r7  r8  s      r&   rb   zVLLMClient.requestp  s     "t!!&3F33r(   c                     |j                   }|rT| j                  5  | xj                  |j                  z  c_        | xj                  |j                  z  c_        ddd       yy# 1 sw Y   yxY w)z'Log the total tokens from the response.Nr
  r   s      r&   r   zVLLMClient.log_usagey  r  r  c                     | j                   j                  d      xs | j                   j                  d      | j                  | j                  di}d| _        d| _        |S r   r   r   s     r&   r   zVLLMClient.get_usage_and_reset  r   r(   c                 n   i | j                   |}	  | j                  |fi |}| j	                  |       |j
                  }|D cg c]  }|j                  j                   }}|||d}| j                  j                  |       |S # t        $ r}t        d|        t        |      d }~ww xY wc c}w )NzFailed to generate completion: r   )
r#   rb   r  r   r   r2   r3   r.   r$   rH   )	r%   r6   r#   r7   r  r2   r   r   r$   s	            r&   rN   zVLLMClient.__call__  s    *DKK*6*	#t||F5f5H
 	x ""<CD&v~~--DD  

 	G$!  	3A378A,	 Es   B B2	B/B**B/)r4   http://localhostnull)rY   rZ   r[   r   r   r'   r  r   r   r   r   r   rz   rb   r   r   rN   r   r   s   @r&   r=  r=  M  s{     /52 N+	2, W	4c 44Gs r(   r=  c                   $     e Zd ZdZd fd	Z xZS )OllamaClientz&A wrapper class for dspy.OllamaClient.c                     |j                  d      s|j                  d      sd|z   }t        |   d|| d| d| i | j                  || _        y)zYCopied from dspy/dsp/modules/hf_client.py with the addition of storing additional kwargs.zhttp://zhttps://r?  )r   r@  Nr   )rF   r   r'   r#   )r%   r   rA  rB  r#   r   s        r&   r'   zOllamaClient.__init__  s[     ~~i(
1Kc/CIu#avI&I///r(   )rI  )rY   rZ   r[   r   r'   r   r   s   @r&   rL  rL    s    00 0r(   rL  c                   &     e Zd Zd fd	Zd Z xZS )	TGIClientc                 .    t        |   d||||d| y )N)r   rA  rB  http_request_kwargsr   )r   r'   )r%   r   rA  rB  rQ  r#   r   s         r&   r'   zTGIClient.__init__  s+     	
 3		

 	
r(   c                    i | j                   |}||d   dkD  |d   |d   dkD  d|d}t        di |d   |d<   t        | j                   dt	        j
                         j                  | j                         dz   f| j                  t        | j                        || j                  d| j                  }	 |j                         }|d	   g}d
|v r#d|d
   v r||d
   d   D cg c]  }|d	   	 c}z  }||D cg c]  }d|i c}d}|S c c}w c c}w # t        $ r" t        d|j                         t        d      w xY w)z^Copied from dspy/dsp/modules/hf_client.py with the addition of removing hard-coded parameters.rO   rX   )	do_samplebest_ofdetails)inputs
parametersrW  r?  z	/generate)rB  portsr   r   generated_textrU  best_of_sequencesr4   r6   r2   zFailed to parse JSON response:z*Received invalid JSON response from serverr   )r#   r
   r   rB  randomRandomr   rX  tupler   rQ  r   r  r   r4   )	r%   r6   r#   payloadr7   json_responser   rv   rJ   s	            r&   	_generatezTGIClient._generate  s   *DKK*6* #C[1_!#;!#;? 	
 !- Ew|/D E 2xxj&--/00<=>L


#LL
 &&
	J$MMOM ))9:;K ]*'=+CC*956IJ  &'  
 #);5Wavqk5WXHO 
 6X 	J2HMMBHII	Js*   <,D (D4
D >D	D 
D +ErQ   )rY   rZ   r[   r'   ra  r   r   s   @r&   rO  rO    s    
1Jr(   rO  c                        e Zd ZdZ	 	 	 	 ddee   ded   f fdZd Zd Z	 e
j                  e
j                  ede	      d
        Z xZS )TogetherClientz"A wrapper class for dspy.Together.rk   r    r   c                    t         |   |d       t        j                         | _        |t
        j                  j                  d      n|x| _        }|| _	        || _
        t        j                  d      | j                  dk(  rd| _        n"d| _        nt        j                  d      | _        || _        | j                  rOt        j                  d	       || j                  }t!        j"                  ||j                  d
d            | _        d}|j                  dd      t'        |j                  dd      d      |j                  dd      |j                  dd      d|j)                  d|j)                  dd            d|vr|n|d   d|| _        t-        j.                         | _        d| _        d| _        y)z_Copied from dspy/dsp/modules/hf_client.py with the support of applying tokenizer chat template.T)r   	is_clientNTOGETHER_API_KEYTOGETHER_API_BASEr/   z,https://api.together.xyz/v1/chat/completionsz'https://api.together.xyz/v1/completionszLoading huggingface tokenizer.	cache_dir)rh  z

---r   rT   r   r   r   r   r!  rX   rO   r"  stop)r   r   r   r!  repetition_penaltyrO   ri  r   )r   r'   r   Sessionsessionrq   r%  rG   rk   r   r    rr   rm   apply_tokenizer_chat_templater  infor   from_pretrained	tokenizerr&  r=   r#   r   r   r   r   r   )	r%   r   rk   rm  hf_tokenizer_namer    r#   stop_defaultr   s	           r&   r'   zTogetherClient.__init__  s    	u5'')29/BJJNN-.w	
w 
$99()1&( N III&9:DM
 .K*--LL9: ($(JJ!*::!VZZT-JDN ! "::mS9fjjt<dCZZ-ZZ+"#C,=q!AB$*&$8LfVn	
 	
 "+!1!"r(   c                    |j                  d      }|r`| j                  5  | xj                  |j                  dd      z  c_        | xj                  |j                  dd      z  c_        ddd       yy# 1 sw Y   yxY wr   r   r   s      r&   r   zTogetherClient.log_usage+  r   r   c                 l    | j                   | j                  | j                  di}d| _        d| _        |S r   r   r   s     r&   r   z"TogetherClient.get_usage_and_reset3  r,  r(   rU   rD  c           	         i | j                   |}|j                  d      }|j                  d      }|j                  dd      }|j                  dd      }|j                  dd      }|j                  d	d
      }| j                  r!| j                  j	                  d|dgd      }| j
                  dk(  r dddd|dg}	| j                  |	||||||d}
n| j                  |||||||d}
dd| j                   i}| j                  j                  | j                  ||
      5 }|j                         }| j                  |       | j
                  dk(  r7|j                  dg       d   j                  di       j                  dd      g}n&|j                  dg       d   j                  dd      g}||D cg c]  }d|i c}d}|cd d d        S c c}w # 1 sw Y   y xY w)Nri  r   r   r   r   gffffff?r!  2   rj  rX   r+   r,   F)tokenizer/   systemzmYou are a helpful assistant. You must continue the user text directly without *any* additional interjections.)r   r1   r   r   r   r!  rj  ri  )r   r6   r   r   r   r!  rj  ri  r   r   r   r2   r   r3   r.   r   r4   r[  )r#   rG   rm  rp  apply_chat_templater    r   rk   rl  r   rm   r   r   )r%   r6   r#   ri  r   r   r   r!  rj  r1   bodyr   resp	resp_jsonr   rJ   r7   s                    r&   ra  zTogetherClient._generate@  s    +DKK*6*zz&!jj/ZZc2


7C(

7B'#ZZ(<a@--^^77 V45 8 F
 ??f$ %  O  F3H $*(&8	D  *(&8	D #gdll^$<=\\t}}gDI 	T		INN9%&( MM)R03SB'SB'  )}}Y;A>BB62NO"(;5Wavqk5WXH	 	 6X	 	s   %BG8GGGG!)NFNr/   )rY   rZ   r[   r   r   rz   r   r'   r   r   r   r   r   r   r   ra  r   r   s   @r&   rc  rc    ss    ,
 "&&+.44# #4# N+4#lQ W	>>r(   rc  c                        e Zd ZdZ	 ddedee   f fdZd Zd ZdefdZ	 e
j                  e
j                  efd	d
ee      defd       Z	 	 ddededefdZ xZS )GoogleModelz&A wrapper class for Google Gemini API.r   rk   c                    t         |   |       	 ddlm} |t
        j                  j                  d      n|}|j                  |       dd|vrdn|d   |d	   ddd
|}|j                  d	d       || _
         |j                  di || _        |j                  || j                        | _        ddi|| _        g | _        t#        j$                         | _        d| _        d| _        y# t        $ r}t	        d      |d}~ww xY w)zDYou can use `genai.list_models()` to get a list of available models.r   Nz7GoogleModel requires `pip install google-generativeai`.GOOGLE_API_KEYr#  rX   r   rT   r   )candidate_countr   max_output_tokensr   r!  )
model_namegeneration_configrO   r   )r   r'   google.generativeaigenerativeair$  rq   r%  rG   	configurer=   r   GenerationConfigconfigGenerativeModelllmr#   r$   r   r   r   r   r   )r%   r   rk   r#   genair'  r   s         r&   r'   zGoogleModel.__init__  s,    		/ 7>o"**..!127(  !$F2}8M!'!5	
 	
 	

<&
,e,,6v6(( ) 

 


 .0!*!1!"I  	I	s   C/ /	D	8DD	c                     |j                   }|rT| j                  5  | xj                  |j                  z  c_        | xj                  |j
                  z  c_        ddd       yy# 1 sw Y   yxY w)z2Log the total tokens from the Google API response.N)usage_metadatar   r   prompt_token_countr   candidates_token_countr   s      r&   r   zGoogleModel.log_usage  sk    ,,
'' L""j&C&CC"&&**K*KK&L L L Lr  c                 l    | j                   | j                  | j                  di}d| _        d| _        |S r   r   r   s     r&   r   zGoogleModel.get_usage_and_reset  r,  r(   r6   c                     |}i | j                   |}|j                  dd       }| j                  j                  ||      }||j	                         g||d}| j
                  j                  |       |S )NrO   )r  r0  )r#   r=   r  generate_contentto_dictr$   rH   )r%   r6   r#   r1  rO   r7   r$   s          r&   r  zGoogleModel.basic_request  s    

kk

 JJsD!88,,Vv,N !))+,$	
 	G$r(   rU   r3  r4  c                 (     | j                   |fi |S )zGHandles retrieval of completions from Google whilst handling API errorsr7  r8  s      r&   rb   zGoogleModel.request  r9  r(   r   r   c                    |sJ d       |du sJ d       |j                  dd      }g }t        |      D ]N  } | j                  |fi |}| j                  |       |j	                  |j
                  d   j                         P |S )Nr   FrO   rX   r   )r=   r;  rb   r   rH   partsr4   )	r%   r6   r   r   r#   rO   r   r   r7   s	            r&   rN   zGoogleModel.__call__  s     (y(~%0y0%JJsAq 	7A#t||F5f5HNN8$x~~a0556	7
 r(   rQ   r   )rY   rZ   r[   r   rz   r   r'   r   r   r  r   r   r   r  r   r	   rb   r   rN   r   r   s   @r&   r~  r~    s    0
 "&.#.# #.#`LC , W	4c 44  $#	  	r(   r~  )r   rW   )Jr   dspy	functoolsr  rq   r\  r   r   typingr   r   r   rB   pathlibr   dspr   r   r	   dsp.modules.hfr
   dsp.modules.hf_clientr   ri   r   r   transformersr   r  r   r$  warningscatch_warningsfilterwarningsUserWarningr%  re   drop_params	telemetrylitellm.caching.cachingr   pathrs   homer   r!   LM_LRU_CACHE_MAX_SIZEr   	lru_cacher>   r?   r@   rA   rz   r}   r   r\   rR   r   r   r   r   r  modulesr   r  r=  OllamaLocalrL  HFClientTGIrO  HFModelrc  r~  r   r(   r&   <module>r     s       	    ) )   2 1 ' @ & &( X HH{;%RZZ75;

12GG *idiik+?@^&A  7" 7"t 23U 4U 48T&J 5
 23 4 9=$+O 4= =3 =4s 4 4C 4L2 LhW$++ Wt\DKK \~Ctww CLo odE$((""%%(( EPW Wt
04## 
0;J   ;J|RT\\ Rj|$((""%%(( |c#  N s   J 5AJJJJ$