
    ih76                         d dl Z d dlZd dlmZ d dlmZ d dlmZmZmZm	Z	m
Z
mZ d dlmZ d dlmZmZ d dlmZ d dlmZmZ d d	lmZmZ  G d
 de      Zdeeef   de
eef   fdZ G d de      Zy)    N)datetime)Enum)AnyDictListOptionalTupleUnion)UUID)AgentActionAgentFinish)BaseCallbackHandler)BaseMessageChatMessage)
Generation	LLMResultc                       e Zd ZdZdZdZy)LabelStudioModezLabel Studio mode enumerator.promptchatN)__name__
__module____qualname____doc__PROMPTCHAT     p/var/www/html/dev/engine/venv/lib/python3.12/site-packages/langchain_community/callbacks/labelstudio_callback.pyr   r      s    'FDr   r   modereturnc                     t         j                  j                  dt         j                  j                  di}t	        | t
              rt        |       } || j                     | fS )zGet default Label Studio configs for the given mode.

    Parameters:
        mode: Label Studio mode ("prompt" or "chat")

    Returns: Tuple of Label Studio config and mode
    a	  
<View>
<Style>
    .prompt-box {
        background-color: white;
        border-radius: 10px;
        box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.1);
        padding: 20px;
    }
</Style>
<View className="root">
    <View className="prompt-box">
        <Text name="prompt" value="$prompt"/>
    </View>
    <TextArea name="response" toName="prompt"
              maxSubmissions="1" editable="true"
              required="true"/>
</View>
<Header value="Rate the response:"/>
<Rating name="rating" toName="prompt"/>
</View>a  
<View>
<View className="root">
     <Paragraphs name="dialogue"
               value="$prompt"
               layout="dialogue"
               textKey="content"
               nameKey="role"
               granularity="sentence"/>
  <Header value="Final response:"/>
    <TextArea name="response" toName="dialogue"
              maxSubmissions="1" editable="true"
              required="true"/>
</View>
<Header value="Rate the response:"/>
<Rating name="rating" toName="dialogue"/>
</View>)r   r   valuer   
isinstancestr)r    _default_label_configss     r   get_default_label_configsr'      sa     	$$ '* 	"" %-'R $t$!$**-t33r   c                       e Zd ZU dZdZeed<   dddedej                  fde	e   de	e   de	e
   ded	e	e   d
eeef   f fdZdedeee      ddfdZdeeef   dee   deddfdZdedefdZdddddeeef   deee      dede	e   de	ee      de	eeef      dedefdZdededdfdZdededdfdZd ededdfd!Zdeeef   d"eeef   deddfd#Zd$eeef   deddfd%Zd ededdfd&Zdeeef   d'ededdfd(Zd)e dedefd*Z!	 	 d4d+ed,e	e   d-e	e   deddf
d.Z"d ededdfd/Z#d0ededdfd1Z$d2e%deddfd3Z& xZ'S )5LabelStudioCallbackHandlera  Label Studio callback handler.
    Provides the ability to send predictions to Label Studio
    for human evaluation, feedback and annotation.

    Parameters:
        api_key: Label Studio API key
        url: Label Studio URL
        project_id: Label Studio project ID
        project_name: Label Studio project name
        project_config: Label Studio project config (XML)
        mode: Label Studio mode ("prompt" or "chat")

    Examples:
        >>> from langchain_community.llms import OpenAI
        >>> from langchain_community.callbacks import LabelStudioCallbackHandler
        >>> handler = LabelStudioCallbackHandler(
        ...             api_key='<your_key_here>',
        ...             url='http://localhost:8080',
        ...             project_name='LangChain-%Y-%m-%d',
        ...             mode='prompt'
        ... )
        >>> llm = OpenAI(callbacks=[handler])
        >>> llm.invoke('Tell me a story about a dog.')
    zLangChain-%Y-%m-%dDEFAULT_PROJECT_NAMENapi_keyurl
project_idproject_nameproject_configr    c                 >   t         |           	 dd l}|snt        j                  d      rt        t        j                  d            }n:t        d| j                  j
                   d| j                  j
                   d      || _
        |sqt        j                  d      rt        j                  d      }nFt        j                  d|j                   d	| j                  j
                   d
       |j                  }|| _        i | _        |j!                  | j                  | j                        | _        || _        |r|| _        d | _        nt+        |      \  | _        | _        |xs t        j                  d      | _        | j,                  4| j"                  j/                  t1        | j,                              | _        nt5        j6                         j9                  | j$                        }| j"                  j;                  |      }	|	r&|	d   | _        | j2                  j<                  | _        nG| j"                  j?                  || j&                        | _        | j2                  j<                  | _        | j2                  j@                  | _         d\  | _!        | _"        | _#        | _$        | j@                  jK                         D ]C  \  }
}|d   dk(  s|
| _!        |d   d   | _"        |d   d   d   | _#        |d   d   d   | _$         n | jB                  sMd| j$                   d}| j(                  tL        jN                  k(  r|dz  }t        |      |dz  }t        |      y # t        $ r$ t        d| j                  j
                   d      w xY w)Nr   zYou're using z in your code, but you don't have the LabelStudio SDK Python package installed or upgraded to the latest version. Please run `pip install -U label-studio-sdk` before using this callback.LABEL_STUDIO_API_KEYz in your code, Label Studio API key is not provided. Please provide Label Studio API key: go to the Label Studio instance, navigate to Account & Settings -> Access Token and copy the key. Use the key as a parameter for the callback: zr(label_studio_api_key='<your_key_here>', ...) or set the environment variable LABEL_STUDIO_API_KEY=<your_key_here>LABEL_STUDIO_URLz5Label Studio URL is not provided, using default URL: z8If you want to provide your own URL, use the parameter: zj(label_studio_url='<your_url_here>', ...) or set the environment variable LABEL_STUDIO_URL=<your_url_here>)r,   r+   LABEL_STUDIO_PROJECT_ID)title)r4   label_config)NNNNtypeTextAreato_nameinputsr#   zLabel Studio project "zI" does not have a TextArea tag. Please add a TextArea tag to the project.z
HINT: go to project Settings -> Labeling Interface -> Browse Templates and select "Generative AI -> Supervised Language Model Fine-tuning" template.z
HINT: go to project Settings -> Labeling Interface -> Browse Templates and check available templates under "Generative AI" section.)(super__init__label_studio_sdkImportError	__class__r   osgetenvr%   
ValueErrorr+   warningswarnLABEL_STUDIO_DEFAULT_URLr,   payloadClient	ls_clientr.   r/   r    r'   r-   get_projectint
ls_projectr   todaystrftimeget_projectsidcreate_projectparsed_label_config	from_namer8   r#   
input_typeitemsr   r   )selfr+   r,   r-   r.   r/   r    lsproject_titleexisting_projectstag_nametag_infoerror_messager>   s                r   r;   z#LabelStudioCallbackHandler.__init__j   ss    			) yy/0bii(>?@ #DNN$;$;#< =D ~~../XY
 
 yy+,ii 23**,*E*E)FN~~../W	X 11 )+txxF("0DDI-Ft-L*D$L		2K(L??&"nn88T__9MNDO$NN,55d6G6GHM $ ; ;- ; P "3A"6"&//"4"4"&.."?"?'d6I6I #@ # #'//"4"4#'??#F#F E
Adj$/ #'":":"@"@"B 	Hh:-!)'	215%h/27;
"*8"4Q"7"?	 ~~():):(; << = 
 yyO222G ]++ / ]++) i  	 7 78 9/ 0 	s   M/ /-Nrun_idgenerationsr!   c                    g }| j                   |   d   }| j                   |   d   j                  di       j                  d      }t        ||      D ]_  \  }}|j                  | j                  |d|i| j
                  | j                  dd|D cg c]  }|j                   c}idg|d	gd
       a | j                  j                  |       y c c}w )Npromptskwargsinvocation_params
model_namer[   textareatext)rQ   r8   r6   r#   )resultmodel_version)datapredictions)
rE   getzipappendr#   rQ   r8   rc   rJ   import_tasks)	rT   r[   r\   tasksr^   re   r   
generationgs	            r   add_prompts_generationsz2LabelStudioCallbackHandler.add_prompts_generations   s     ,,v&y1LL *S$b)S 	
 #&g{"; 	FJLL 

F & 26/3||,6.4z6R!qvv6R-S	!"' .;
$	, 	$$U+ 7Ss   C
serializedr^   r_   c                     | j                   dk7  r&t        d| j                   d| j                    d      t        |d         }||d| j                  |<   y).Save the prompts in memory when an LLM starts.Text
Label Studio project "" has an input type <zw>. To make it work with the mode="chat", the input type should be <Text>.
Read more here https://labelstud.io/tags/textr[   )r^   r_   N)rR   rA   r.   r%   rE   )rT   rp   r^   r_   r[   s        r   on_llm_startz'LabelStudioCallbackHandler.on_llm_start  sj     ??f$*4+<+<*= >&&*oo%6 7@A  VH%&+2fEVr   messagec                 f    t        |t              r|j                  S |j                  j                  S )zGet the role of the message.)r$   r   roler>   r   )rT   rw   s     r   _get_message_rolez,LabelStudioCallbackHandler._get_message_role  s(    g{+<<$$---r   )parent_run_idtagsmetadatamessagesr{   r|   r}   c                L   | j                   dk7  r&t        d| j                   d| j                    d      g }|D ]I  }	g }
|	D ]/  }|
j                  | j	                  |      |j
                  d       1 |j                  |
       K ||||||d| j                  t        |      <   y)rr   
Paragraphsrt   ru   z>. To make it work with the mode="chat", the input type should be <Paragraphs>.
Read more here https://labelstud.io/tags/paragraphs)ry   content)r^   r|   r}   r[   r{   r_   N)rR   rA   r.   rj   rz   r   rE   r%   )rT   rp   r~   r[   r{   r|   r}   r_   r^   message_listdialogrw   s               r   on_chat_model_startz.LabelStudioCallbackHandler.on_chat_model_start  s     ??l**4+<+<*= >&&*oo%6 7FG  $ 		#LF'  $ 6 6w ?#*?? NN6"		#  *%
S[!r   tokenc                      y)z)Do nothing when a new token is generated.Nr   )rT   r   r_   s      r   on_llm_new_tokenz+LabelStudioCallbackHandler.on_llm_new_tokenG      r   responsec                     t        |d         }| j                  ||j                         | j                  j	                  |       y)z>Create a new Label Studio task for each prompt and generation.r[   N)r%   ro   r\   rE   pop)rT   r   r_   r[   s       r   
on_llm_endz%LabelStudioCallbackHandler.on_llm_endK  s=    VH%& 	$$VX-A-AB 	 r   errorc                      y)z%Do nothing when LLM outputs an error.Nr   rT   r   r_   s      r   on_llm_errorz'LabelStudioCallbackHandler.on_llm_errorU  r   r   r9   c                      y Nr   )rT   rp   r9   r_   s       r   on_chain_startz)LabelStudioCallbackHandler.on_chain_startY  s     	r   outputsc                      y r   r   )rT   r   r_   s      r   on_chain_endz'LabelStudioCallbackHandler.on_chain_end^  s    r   c                      y)z+Do nothing when LLM chain outputs an error.Nr   r   s      r   on_chain_errorz)LabelStudioCallbackHandler.on_chain_errora  r   r   	input_strc                      y)zDo nothing when tool starts.Nr   )rT   rp   r   r_   s       r   on_tool_startz(LabelStudioCallbackHandler.on_tool_starte  s     	r   actionc                      y)z.Do nothing when agent takes a specific action.Nr   )rT   r   r_   s      r   on_agent_actionz*LabelStudioCallbackHandler.on_agent_actionn  r   r   outputobservation_prefix
llm_prefixc                      y)zDo nothing when tool ends.Nr   )rT   r   r   r   r_   s        r   on_tool_endz&LabelStudioCallbackHandler.on_tool_endr  s     	r   c                      y)z&Do nothing when tool outputs an error.Nr   r   s      r   on_tool_errorz(LabelStudioCallbackHandler.on_tool_error|  r   r   rc   c                      yz
Do nothingNr   )rT   rc   r_   s      r   on_textz"LabelStudioCallbackHandler.on_text  r   r   finishc                      yr   r   )rT   r   r_   s      r   on_agent_finishz*LabelStudioCallbackHandler.on_agent_finish  r   r   )NN)(r   r   r   r   r*   r%   __annotations__r   r   r   rI   r
   r;   r   r   ro   r   r   rv   r   rz   r   r   r   r   r   BaseExceptionr   r   r   r   r   r   r   r   r   r   r   r   __classcell__)r>   s   @r   r)   r)   N   s1   2 !5#4 "&!$(0(,,;,B,Bv,#v, c]v, SM	v,
 v, !v, C()v,p!,!,(,T*-=(>!,	!,FFcNF cF 	F
 
F$. . . )-$(-1'
cN'
 tK()'

 '
  ~'
 tCy!'
 4S>*'
 '
 
'
Rc S T !9 ! ! !- 3 4 sCx.26sCx.LO	
DcN c d M S T cN  	
 
k S S  -1$(	 %SM SM	
  
= C D C 3 4 k S T r   r)   )r?   rB   r   enumr   typingr   r   r   r   r	   r
   uuidr   langchain_core.agentsr   r   langchain_core.callbacksr   langchain_core.messagesr   r   langchain_core.outputsr   r   r   r%   r'   r)   r   r   r   <module>r      sk    	    : :  : 8 < 8d 64
_$
%64
3 64rx!4 xr   