o
    iw`                     @   s0  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
mZ d dlmZmZ d dlZd dlZd dlZd dlmZmZ d dlmZ d dlmZ zd dlZW n	 eya   Y nw e dkrld dlZe rd d	lmZ d d
lm Z  d dl!m"Z" dddZ#e$ej%ej& Z'e$ej%ej( ej& d Z)ddiddiddiddiddiddiddidZ*dZ+dd,e*-  dZ.G dd dZ/G dd  d Z0d!e1dB d"efd#d$Z2d%e3e1 dB d"e4fd&d'Z5d5d(e1dB d"e3e4 fd)d*Z6d+e1d,e3e4 d-e4d"e1fd.d/Z7d"e1fd0d1Z8e9d2kre0d3d4 dS dS )6    N)AsyncIterator)	AnnotatedAny)urljoinurlparse)AsyncInferenceClientChatCompletionStreamOutput)GenerationConfig)is_rich_availableWindows)Console)Live)Markdown	localhosti@  )hostnameportz .!\"#$%&'()*+,\-/:<=>?@[]^_`{|}~textz5There is a Llama in my lawn, how can I get rid of it?zyWrite a Python function that integrates any Python function f(x) numerically over an arbitrary interval [x_start, x_end].z4How many helicopters can a human eat in one sitting?z4Count to 10 but skip every number ending with an 'e'zWhy aren't birds real?z2Why is it important to eat socks after meditating?z$Which number is larger, 9.9 or 9.11?)llamacode
helicopternumbersbirdssocksnumbers2a  

**TRANSFORMERS CHAT INTERFACE**

Chat interface to try out a model. Besides chatting with the model, here are some basic commands:
- **!help**: shows all available commands (set generation settings, save chat, etc.)
- **!status**: shows the current status of the model and generation settings
- **!clear**: clears the current conversation and starts a new one
- **!exit**: closes the interface
am  

**TRANSFORMERS CHAT INTERFACE HELP**

Full command list:
- **!help**: shows this help message
- **!clear**: clears the current conversation and starts a new one
- **!status**: shows the current status of the model and generation settings
- **!example {NAME}**: loads example named `{NAME}` from the config and uses it as the user input.
Available example names: `z`, `a#  `
- **!set {ARG_1}={VALUE_1} {ARG_2}={VALUE_2}** ...: changes the system prompt or generation settings (multiple
settings are separated by a space). Accepts the same flags and format as the `generate_flags` CLI argument.
If you're a new user, check this basic flag guide: https://huggingface.co/docs/transformers/llm_tutorial#common-options
- **!save {SAVE_NAME} (optional)**: saves the current chat and settings to file by default to
`./chat_history/{MODEL_ID}/chat_{DATETIME}.yaml` or `{SAVE_NAME}` if provided
- **!exit**: closes the interface
c                   @   s   e Zd ZdedefddZdee deeeeB dB f fdd	Z	defd
dZ
dd ZdefddZdedefddZddededefddZddefddZdefddZdS ) RichInterfacemodel_iduser_idc                 C   s   t  | _|| _|| _d S N)r   _consoler   r   )selfr   r    r    W/sda-disk/www/egybert/egybert_env/lib/python3.10/site-packages/transformers/cli/chat.py__init__g   s   
zRichInterface.__init__streamreturnNc           
         s  | j d| j d t| j ddg}d}d }|I d H 2 zT3 d H W }|jd jj}t|jd d|}|s6qt	dd	|}||7 }g }|
 D ]}|| |d
rY|d qG|d qGtd| dd}	|j|	dd q6 W d    n1 s}w   Y  | j   ||fS )Nz[bold blue]<z>:   )consolerefresh_per_second r   finish_reasonz<(/*)(\w*)>z\<\1\2\>z```
z  
zgithub-dark)
code_themeT)refresh)r   printr   r   choicesdeltacontentgetattrresub
splitlinesappend
startswithr   joinstripupdate)
r   r#   liver   r)   tokenoutputslineslinemarkdownr    r    r!   stream_outputl   s0   


*zRichInterface.stream_outputc                 C   s$   | j d| j d}| j   |S )z!Gets user input from the console.[bold red]<z>:
)r   inputr   r-   )r   rB   r    r    r!   rB      s   
zRichInterface.inputc                 C   s   | j   dS )zClears the console.N)r   clear)r   r    r    r!   rC      s   zRichInterface.clearr   c                 C   s(   | j d| j d|  | j   dS )z%Prints a user message to the console.rA   z>:[/ bold red]
N)r   r-   r   )r   r   r    r    r!   print_user_message   s   z RichInterface.print_user_messagecolorc                 C   s&   | j d| d|  | j   dS )z,Prints text in a given color to the console.z[bold ]N)r   r-   )r   r   rE   r    r    r!   print_color      zRichInterface.print_colorFmessagedefaultc                 C   sL   |rdnd}| j d| d| d}| j   |  }|s"|S |dv S )zFDisplays a yes/no prompt to the user, returning True for confirmation.zY/nzy/Nz[bold yellow]z (z): >   yyes)r   rB   r-   r8   lower)r   rI   rJ   default_hintresponser    r    r!   confirm   s   
zRichInterface.confirmminimalc                 C   s&   | j t|rtnt | j   dS )z'Prints the help message to the console.N)r   r-   r   HELP_STRING_MINIMALHELP_STRING)r   rQ   r    r    r!   
print_help   rH   zRichInterface.print_helpconfigc                 C   s6   | j d| j d | j d|  | j   dS )zFPrints the status of the model and generation settings to the console.z[bold blue]Model: r*   z[bold blue]N)r   r-   r   )r   rU   r    r    r!   print_status   s   zRichInterface.print_status)F)__name__
__module____qualname__strr"   r   r   tupler   r@   rB   rC   rD   rG   boolrP   rT   r	   rV   r    r    r    r!   r   f   s    &0r   c                   @   sT  e Zd ZdZded  ded  ddddddfdeeejd	d
f deedB ejdd
f dee	e dB ejdd
f deedB ej
dd
f deedB ej
dd
f deeej
dd
f deedB ej
dd
f deedB ej
dd
f ddfddZedd Zdeded eeeeef f d!ed"e	e dee	e ef fd#d$Zd%d& ZdS )'Chat(Chat with a model from the command line.zhttp://r   :r   Nz./chat_history/r   z9ID of the model to use (e.g. 'HuggingFaceTB/SmolLM3-3B').)helpbase_urlz7Base url to connect to (e.g. http://localhost:8000/v1).generate_flagsa  Flags to pass to `generate`, using a space as a separator between flags. Accepts booleans, numbers, and lists of integers, more advanced parameterization should be set through --generation-config. Example: `transformers chat <base_url> <model_id> max_new_tokens=100 do_sample=False eos_token_id=[1,2]`. If you're a new user, check this basic flag guide: https://huggingface.co/docs/transformers/llm_tutorial#common-optionsuserzKUsername to display in chat interface. Defaults to the current user's name.system_promptzSystem prompt.save_folderzFolder to save chat history.examples_pathz"Path to a yaml file with examples.generation_configzPath to a local generation config file or to a HuggingFace repo containing a `generation_config.json` file. Other generation settings passed as CLI arguments will be applied on top of this generation config.r$   c	                 C   s  || _ t| j }	|	jtd kr|	jtd kr| | j  || _|| _|| _t	|}
|
j
ddd |
j
d	i t| |
| _||| j d| _|durM|nt | _|rnt|}t|| _W d   n1 shw   Y  nt| _t sxtdt|   dS )
r^   r   r   T   )	do_samplemax_new_tokens)ra   r   rU   NzHYou need to install rich to use the chat interface. (`pip install rich`)r    )ra   r   r   DEFAULT_HTTP_ENDPOINTr   check_healthr   rd   re   load_generation_configr9   parse_generate_flagsrU   to_dictsettingsget_usernamerc   openyaml	safe_loadexamplesDEFAULT_EXAMPLESr
   ImportErrorasynciorun
_inner_run)r   r   ra   rb   rc   rd   re   rf   rg   parsedrU   fr    r    r!   r"      s,   #

zChat.__init__c                 C   sb   t | d d}zt|}|jdkrtd|  d|j dW d	S  tjy0   td|  dw )
N/health   zThe server running on z returned status code z on health check (/health).zNo server currently running on z. To run a local server, please run `transformers serve` in aseparate shell. Find more information here: https://huggingface.co/docs/transformers/servingT)r   httpxgetstatus_code
ValueErrorConnectError)url
health_urloutputr    r    r!   rl     s   



zChat.check_health
user_input	interfaceru   rU   chatc                 C   s  d}|dkrt | j}|  n|dkr|  n|drYt| dk rY| }t|dkr4|d ntj	| j
| jdtd d	}t||| jd
 |jd| ddd n|dr|dd  }	|	 }	|	D ]}
d|
vr|jd|
 ddd  nql|jd"i t|	 nd|drt| dkr| d }||v r|  g }||| d  |d|| d d n1d| dt|  d}|j|dd n|dkr|j|d nd}|jd | d!dd |  |||fS )#z
        Handles all user commands except for `!exit`. May update the chat history (e.g. reset it) or the
        generation config (e.g. set a new flag).
        T!clear!help!save      chat_%Y-%m-%d_%H-%M-%S.jsonfilenamer   rp   Chat saved to !greenr   rE   !setr%   N=(Invalid flag format, missing `=` after `;`. Please use the format `arg_1=value_1 arg_2=value_2 ...`.red!exampler   rc   roler0   Example * not found in list of available examples: .!statusrU   F'/' is not a valid command. Showing help message.r    )new_chat_historyrd   rC   rT   r6   lensplitospathr7   re   r   timestrftime	save_chatrp   rG   r8   r9   rn   rD   r5   listkeysrV   )r   r   r   ru   rU   r   valid_commandsplit_inputr   new_generate_flagsflagexample_nameexample_errorr    r    r!   handle_non_exit_user_commands$  sV   


 


z"Chat.handle_non_exit_user_commandsc              	      sT  t | j| jd}|  t| j}|jdd | j}t| j	d4 I d H v}d }	 zZ|d ur:|}d }|
| n| }|dkrEW nL|dkrTt| j}|  W q)|dkr^|  W q)|drt| d	k r| }t|d	kry|d
 ntj| j| jdtd d}t||| jd |jd| ddd W q)|dr|dd   }	|	 }	|	D ]}
d|
vr|jd|
 ddd  nq|jd,i t|	 W q)|dr!t| d	kr!| d
 }|| jv r|  g }|
| j| d  |d| j| d d nBd| dt| j  d}|j|dd n,|d kr.|j|d! W q)|drE|jd"| d#dd |  W q)|d|d |j |d| j|! | jd$d%}|"|I d H \}}|d&|d |d'kr|d(d) |#d*rd+}W q)W n
 t$y   Y nw q*W d   I d H  d S 1 I d H sw   Y  d S )-N)r   r   T)rQ   )ra   z!exitr   r   r   r   r   r   r   r   r   r   r   r   r   r   r%   r   r   r   r   r   r   rc   r   r   r   r   r   r   r   r   )rg   model)r#   r   
extra_body	assistantlengthz2Generation stopped after reaching the token limit.yellowzContinue generating?u'   Please continue. Do not repeat text.”r    )%r   r   rc   rC   r   rd   rT   rU   r   ra   rD   rB   r6   r   r   r   r   r7   re   r   r   r   rp   rG   r8   r9   rn   ru   r5   r   r   rV   chat_completionto_json_stringr@   rP   KeyboardInterrupt)r   r   r   rU   clientpending_user_inputr   r   r   r   r   r   r   r#   model_outputr)   r    r    r!   rz   n  s   






0zChat._inner_run)rW   rX   rY   __doc__rk   r   rZ   typerArgumentr   Optionr"   staticmethodrl   r   dictr	   r[   r   rz   r    r    r    r!   r]      s|    	

!
F

Jr]   rg   r$   c                 C   sD   | d u rt  S d| v rtj| }tj| }t ||S t | S )Nr   )r	   r   r   dirnamebasenamefrom_pretrained)rg   r   r   r    r    r!   rm     s   
rm   rb   c                    s  | du s
t | dkri S dd | D }dd | D }dd | D }dtdtfd	d
  fdd| D }ddd | D }d| d }|dd}|dd}|dd}|dd}|dd}|dd}zt|}W |S  tjy   t	dw )zUParses the generate flags from the user input into a dictionary of `generate` kwargs.Nr   c                 S   s.   i | ]}d | dd  d  | dd qS )"r   r   r   )r   ).0r   r    r    r!   
<dictcomp>  s   . z(parse_generate_flags.<locals>.<dictcomp>c                 S   s*   i | ]\}}||  d v r|  n|qS ))truefalse)rM   r   kvr    r    r!   r     s    c                 S   s"   i | ]\}}||d krdn|qS )Nonenullr    r   r    r    r!   r     s   " sr$   c                 S   s   |  d} | ddd S )N-r   r(   r   )removeprefixreplaceisdigit)r   r    r    r!   	is_number   s   
z'parse_generate_flags.<locals>.is_numberc                    s*   i | ]\}}| |sd | d n|qS )r   r    r   r   r    r!   r     s   * z, c                 S   s   g | ]\}}| d | qS )z: r    r   r    r    r!   
<listcomp>
  s    z(parse_generate_flags.<locals>.<listcomp>{}z"null"r   z"true"r   z"false"r   z"[[z]"rF   r   r_   zFailed to convert `generate_flags` into a valid JSON object.
`generate_flags` = {generate_flags}
Converted JSON string = {generate_flags_string})
r   itemsrZ   r\   r7   r   jsonloadsJSONDecodeErrorr   )rb   generate_flags_as_dictgenerate_flags_stringprocessed_generate_flagsr    r   r!   rn     s2   rn   rd   c                 C   s   | rd| dgS g S )z Returns a new chat conversation.systemr   r    )rd   r    r    r!   r   $  s   r   r   r   rp   c                 C   sb   t jt j| dd t| d}tj||d|dd W d   n1 s&w   Y  t j| S )z!Saves the chat history to a file.T)exist_okw)rp   chat_historyr%   )indentN)r   makedirsr   r   rr   r   dumpabspath)r   r   rp   r|   r    r    r!   r   )  s
   r   c                   C   s$   t  dkr
t S tt jS )z)Returns the username of the current user.r   )platformr   r   getloginpwdgetpwuidgetuidpw_namer    r    r    r!   rq   1  s   rq   __main__z meta-llama/Llama-3.2-3b-Instruct)r   r   ):rx   r   r   r   r2   stringr   collections.abcr   typingr   r   urllib.parser   r   r   r   rs   huggingface_hubr   r   transformersr	   transformers.utilsr
   readlinerw   r   r   rich.consoler   	rich.liver   rich.markdownr   rk   setascii_letters
whitespaceALLOWED_KEY_CHARSdigitsALLOWED_VALUE_CHARSrv   rR   r7   r   rS   r   r]   rZ   rm   r   r   rn   r   r   rq   rW   r    r    r    r!   <module>   st   
	b  6
