o
    ~rin                     @   sl  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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ye   Y nw e dkrpd dlZe rd d	lmZ d d
l m!Z! d dl"m#Z# d dl$m%Z% d dl&m'Z'm(Z(m)Z)m*Z*m+Z+ d dl,m-Z- dddZ.e/ej0ej1 Z2e/ej0ej3 ej1 d Z4ddiddiddiddiddiddiddidZ5dZ6dd7e58  dZ9G d d! d!Z:G d"d# d#Z;d$e<dB d%efd&d'Z=d(e>e< dB d%e?fd)d*Z@d8d+e<dB d%e>e? fd,d-ZAd.e<d/e>e? d0e?d%e<fd1d2ZBd%e<fd3d4ZCeDd5kr4e;d6d7 dS dS )9    N)AsyncIterator)	AnnotatedAny)urljoinurlparse)AsyncInferenceClientChatCompletionStreamOutput)GenerationConfig)is_rich_availableWindows)filesize)Console)Live)Markdown)	BarColumnProgressProgressColumn
TextColumnTimeElapsedColumn)Text	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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 efd!d"ZdS )$RichInterfacemodel_iduser_idbase_urlc                 C   s   t  | _|| _|| _|| _d S N)r   _consoler"   r#   r$   )selfr"   r#   r$    r(   c/lsinfo/ai/hellotax_ai/llm_service/venv_embed/lib/python3.10/site-packages/transformers/cli/chat.py__init__k   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   r1   tokenoutputslineslinemarkdownr(   r(   r)   stream_outputq   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#   r5   )r'   rJ   r(   r(   r)   rJ      s   
zRichInterface.inputc                 C   s   | j   dS )zClears the console.N)r&   clear)r'   r(   r(   r)   rK      s   zRichInterface.clearr   c                 C   s(   | j d| j d|  | j   dS )z%Prints a user message to the console.rI   z>:[/ bold red]
N)r&   r5   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&   r5   )r'   r   rM   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&   rJ   r5   r@   lower)r'   rQ   rR   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&   r5   r   HELP_STRING_MINIMALHELP_STRING)r'   rY   r(   r(   r)   
print_help   rP   zRichInterface.print_helpmodelc              	      s  t j| jd dd idd}|  G dd dt}dd	d
dd| jjt d d k fdd}t	t
dtdd| t | jd}|j|dd d}d}t|| jddr | D ]e}|rj|dskqat|dd  }	|	d}
|
dkr|	dd} nB|
dkrt|	dd |
d!kr|	d"}|	d#}||}|r|d$krd%nd&}|j|||d' |d(|d) qa|j||d*d d+ qaW d    n1 sw   Y  |r| jtd,  d- n| jtd,  d. | j  d S )/N/z/load_modelr]   T)jsonr+   c                   @   s   e Zd Zdd ZdS )z3RichInterface.print_model_load.<locals>.StatsColumnc                 S   s   |j stdS |jddkrZtt|j}tt|j }|jr.dtt|j dnd}|j	d urIdt|j	d  dt|j	d d}nd}t| d	| | | d
dS tt|j d	t|j  S )Nr0   unitbytesz  z/s<   :02dr^   zprogress.download)style)
totalr   fieldsgetr   decimalint	completedspeedtime_remaining)r'   taskdonetotrl   etar(   r(   r)   render   s   "
(z:RichInterface.print_model_load.<locals>.StatsColumn.renderN)__name__
__module____qualname__rr   r(   r(   r(   r)   StatsColumn   s    rv   zLoading processorzLoading configzDownloading fileszLoading into memory)	processorconfigdownloadweights   F   c                    s"    | | }r  d| S |S )Nu     →  )rh   )	stage_key
stage_textr]   show_model_prefixstage_labelsr(   r)   _label   s   z.RichInterface.print_model_load.<locals>._labelz[bold]{task.description}(   )	bar_width)r.   rw   )rf   F)r.   	transients   data:    statusreadycachederrorrQ   zUnknown errorloadingstageprogressry   ra   itemscurrentrf   )descriptionrk   rf   r`   r   )r   rk   rf   z_*z was already loaded.*_z is warm.*_)requestspostr$   rstripraise_for_statusr   r&   widthlenr   r   r   r   add_taskr   
iter_linesr>   r_   loadsrh   RuntimeErrorrA   r5   r   )r'   r]   rW   rv   r   r   task_idr   rF   eventr   r   proglabelr`   r(   r   r)   print_model_load   s\   "	


zRichInterface.print_model_loadrx   c                 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: r2   z[bold blue]N)r&   r5   r"   )r'   rx   r(   r(   r)   print_status  s   zRichInterface.print_status)F)rs   rt   ru   strr*   r   r   tupler   rH   rJ   rK   rL   rO   boolrX   r\   r   r	   r   r(   r(   r(   r)   r!   j   s    &0Rr!   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   rc   r   Nz./chat_history/r"   z9ID of the model to use (e.g. 'HuggingFaceTB/SmolLM3-3B').)helpr$   z7Base 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)r$   r"   rx   NzHYou need to install rich to use the chat interface. (`pip install rich`)r(   )r$   r   r   DEFAULT_HTTP_ENDPOINTr   check_healthr"   r   r   load_generation_configrA   parse_generate_flagsrx   to_dictsettingsget_usernamer   openyaml	safe_loadexamplesDEFAULT_EXAMPLESr
   ImportErrorasynciorun
_inner_run)r'   r"   r$   r   r   r   r   r   r   parsedrx   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 )
Nr^   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   httpxrh   status_code
ValueErrorConnectError)url
health_urloutputr(   r(   r)   r   j  s   



zChat.check_health
user_input	interfacer   rx   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   r   Chat saved to !greenr   rM   !setr-   N=(Invalid flag format, missing `=` after `;`. Please use the format `arg_1=value_1 arg_2=value_2 ...`.red!exampler   r   roler8   Example * not found in list of available examples: .!statusrx   F'/' is not a valid command. Showing help message.r(   )new_chat_historyr   rK   r\   r>   r   splitospathr?   r   r"   timestrftime	save_chatr   rO   r@   rA   r   rL   r=   listkeysr   )r'   r   r   r   rx   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              	      sd  t | j| j| jd}|  t| j}|jdd || j | j	}t
| jd4 I d H v}d }	 zZ|d urB|}d }|| n| }|dkrMW nL|dkr\t| j}|  W q1|dkrf|  W q1|drt| d	k r| }t|d	kr|d
 ntj| j| jdtd d}t||| jd |jd| ddd W q1|dr|dd   }	|	 }	|	D ]}
d|
vr|jd|
 ddd  nq|jd,i t|	 W q1|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r6|j |d! W q1|drM|jd"| d#dd |  W q1|d|d |j!|d| j|" | jd$d%}|#|I d H \}}|d&|d |d'kr|d(d) |$d*rd+}W q1W n
 t%y   Y nw q2W d   I d H  d S 1 I d H sw   Y  d S )-N)r"   r#   r$   T)rY   )r$   z!exitr   r   r   r   r   r   r   r   r   r   r   r   r   r   r-   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r]   )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"   r   r$   rK   r   r   r\   r   rx   r   rL   rJ   r>   r   r   r   r   r?   r   r   r   r   r   rO   r@   rA   r   r   r=   r   r   r   chat_completionto_json_stringrH   rX   KeyboardInterrupt)r'   r   r   rx   clientpending_user_inputr   r   r   r   r   r   r   r+   model_outputr1   r(   r(   r)   r     s   






0zChat._inner_run)rs   rt   ru   __doc__r   r   r   typerArgumentr   Optionr*   staticmethodr   r!   dictr	   r   r   r   r(   r(   r(   r)   r     s|    	

!
F

Jr   r   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)r   r  r   r(   r(   r)   r   :  s   
r   r   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>N  s   . z(parse_generate_flags.<locals>.<dictcomp>c                 S   s*   i | ]\}}||  d v r|  n|qS ))truefalse)rU   r  kvr(   r(   r)   r  R  s    c                 S   s"   i | ]\}}||d krdn|qS )Nonenullr(   r  r(   r(   r)   r  U  s   " sr,   c                 S   s   |  d} | ddd S )N-r   r0   r   )removeprefixreplaceisdigit)r  r(   r(   r)   	is_numberX  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>b  s    z(parse_generate_flags.<locals>.<listcomp>{}z"null"r  z"true"r  z"false"r  z"[[z]"rN   r   rc   zFailed to convert `generate_flags` into a valid JSON object.
`generate_flags` = {generate_flags}
Converted JSON string = {generate_flags_string})
r   r   r   r   r?   r  r_   r   JSONDecodeErrorr   )r   generate_flags_as_dictgenerate_flags_stringprocessed_generate_flagsr(   r  r)   r   F  s2   r   r   c                 C   s   | rd| dgS g S )z Returns a new chat conversation.systemr   r(   )r   r(   r(   r)   r   |  s   r   r   r   r   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)r   chat_historyr-   )indentN)r   makedirsr   r  r   r_   dumpabspath)r   r   r   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)   r     s   r   __main__z meta-llama/Llama-3.2-3b-Instruct)r"   r%   )Er   r_   r   r/  r:   stringr   collections.abcr   typingr   r   urllib.parser   r   r   r   r  r   huggingface_hubr   r   transformersr	   transformers.utilsr
   readliner   r'  r1  richr   rich.consoler   	rich.liver   rich.markdownr   rich.progressr   r   r   r   r   	rich.textr   r   setascii_letters
whitespaceALLOWED_KEY_CHARSdigitsALLOWED_VALUE_CHARSr   rZ   r?   r   r[   r!   r   r   r   r   r
  r   r   r   r   rs   r(   r(   r(   r)   <module>   s~   
	 6  6
