
    f3fiA                     T   d 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
mZmZ ddlmZmZmZ dd	lmZmZmZ dd
lmZmZ  ej0                  e      ZdZdZ G d d      Z	 	 ddee   dedeee ef      de	e!   de	e   de"e	ee ef      e	e   f   fdZ#deddfdZ$dedefdZ%y)z,Client instrumentation for Claude Agent SDK.    N)AsyncGenerator)datetimetimezone)AnyOptional)get_current_run_treetrace   )clear_active_tool_runspost_tool_use_hookpre_tool_use_hook)build_llm_input!extract_usage_from_result_messageflatten_content_blocks)clear_parent_run_treeset_parent_run_treezclaude.conversationzclaude.assistant.turnc                       e Zd ZdZddee   fdZ	 ddededee	e
ef      dee   d	ee	e
ef      f
d
ZddZde	e
ef   d	dfdZddZy)TurnLifecyclezHTrack ongoing model runs so consecutive messages are recorded correctly.Nquery_start_timec                      d | _         || _        y N)current_runnext_start_time)selfr   s     m/var/www/auto_recruiter/arenv/lib/python3.12/site-packages/langsmith/integrations/claude_agent_sdk/_client.py__init__zTurnLifecycle.__init__   s    *.0@    messageprompthistoryparentreturnc                    | j                   xs t        j                         }| j                  r4| j                  j                          | j                  j	                          t        |g||||      \  }}|| _        d| _         |S )z/Begin a new model run, ending any existing one.)
start_timer!   N)r   timer   endpatch%begin_llm_run_from_assistant_messages)r   r   r   r    r!   startfinal_outputruns           r   start_llm_runzTurnLifecycle.start_llm_run    s{     $$3		  """$AIvw5
c #r   c                 6    t        j                          | _        y)z0Mark when the next assistant message will start.N)r%   r   r   s    r   mark_next_startzTurnLifecycle.mark_next_start5   s    #yy{r   metricsc                     | j                   r|sy| j                   j                  j                  di       j                  di       }|j                  |       y)z.Attach token usage details to the current run.Nmetadatausage_metadata)r   extra
setdefaultupdate)r   r0   metas      r   	add_usagezTurnLifecycle.add_usage9   sL      W%%00R@KKb
 	Gr   c                     | j                   r<| j                   j                          | j                   j                          d| _         yy)zEnd any open run gracefully.N)r   r&   r'   r.   s    r   closezTurnLifecycle.closeB   s<      """$#D r   r   )r"   N)__name__
__module____qualname____doc__r   floatr   r   listdictstrr,   r/   r8   r:    r   r   r   r      s    RA% A !%  d38n%	
  
$sCx.	!*+c3h D $r   r   messagesr   r    r$   r!   r"   c                    | rt        | d         j                  dk7  ry| d   }t        |dd      }|
t               }|syt	        ||      }| D cg c]&  }t        |d      rt        |j                        dd( }	}|j                  t        d	|rd
|ini t        |	      dk(  r|	d   nd|	i|rdd|iini |r%t        j                  |t        j                        nd      }
	 |
j                          t        |d      rt        |j                        ddnd}||
fS c c}w # t         $ r"}t"        j%                  d|        Y d}~Ud}~ww xY w)z2Create a traced model run from assistant messages.AssistantMessageNNmodelNcontent	assistantrJ   rolellmrD   r
   r2   ls_model_nametz)namerun_typeinputsoutputsr4   r$   zFailed to post LLM run: )typer;   getattrr   r   hasattrr   rJ   create_childLLM_RUN_NAMElenr   fromtimestampr   utcpost	Exceptionloggerwarning)rD   r   r    r$   r!   last_msgrI   rT   mrU   llm_runefinal_contents                r   r(   r(   J   so    tHRL)226HH|HHgt,E~%'VW-F 1i  +1995{KG  !!'-
F#2"7|q0y'6J8=zOU342 ))*F " 	G7 8Y' +8+;+;<kR 
 '!!7&  71!5667s   +D#D" "	E+EEoptionsc                 B   t        | d      sy| j                  i | _        d| j                  vrg | j                  d<   d| j                  vrg | j                  d<   	 ddlm}  |dt        g      } |dt
        g      }| j                  d   j                  d|       | j                  d   j                  d|       t        j                  d       y# t        $ r t        j                  d	       Y yt        $ r"}t        j                  d
|        Y d}~yd}~ww xY w)a  Inject LangSmith tracing hooks into ClaudeAgentOptions.

    This adds PreToolUse and PostToolUse hooks to capture ALL tool calls
    (built-in, external MCP, and SDK MCP). The hooks work across all LLM
    providers (Anthropic, Vertex AI, Kimi, etc.) because they use explicit
    tool_use_id correlation instead of relying on async context propagation.

    Args:
        options: ClaudeAgentOptions instance to modify
    hooksN
PreToolUsePostToolUser   )HookMatcher)matcherri   z8Injected LangSmith tracing hooks into ClaudeAgentOptionsz2Failed to import HookMatcher from claude_agent_sdkz Failed to inject tracing hooks: )rX   ri   claude_agent_sdkrl   r   r   insertr`   debugImportErrorra   r_   )rg   rl   langsmith_pre_matcherlangsmith_post_matcherre   s        r   _inject_tracing_hooksrt   {   s    7G$ }} 7==(&(l# GMM)')m$?0 +DAR@S T!,TBTAU!Vl#**1.CDm$++A/EFOP MKL ?9!=>>?s   A7C D4D<DDoriginal_classc                      G d d|       }|S )zHWrap `ClaudeSDKClient` to trace both `query()` and `receive_response()`.c                        e Zd Zdedef fdZdededef fdZdededeeef   dd	fd
Zde	ed	f   f fdZ
d fdZdedd	f fdZ xZS )7instrument_claude_client.<locals>.TracedClaudeSDKClientargskwargsc                     |j                  d      xs	 |r|d   nd }|rt        |       t        |   |i | d | _        d | _        y )Nrg   r   )getrt   superr   _prompt_start_time)r   ry   rz   rg   	__class__s       r   r   z@instrument_claude_client.<locals>.TracedClaudeSDKClient.__init__   sJ    jj+J4QTG%g.Gd-f-*.DL04Dr   r"   c                    K   t        j                          | _        t        |j                  d      xs	 |r|d   nd      | _        t        |   |i | d{   S 7 w)z/Capture prompt and timestamp when query starts.r   r    N)r%   r   rB   r|   r~   r}   query)r   ry   rz   r   s      r   r   z=instrument_claude_client.<locals>.TracedClaudeSDKClient.query   sQ     #yy{Dvzz(3P4QRQDL77777s   AA AA msgr+   subagent_sessionsNc           
         t        |d      syddlm} t        |dd      }|j                  D ]`  }t        |      j                  dk7  r	 t        |dd      }t        |dd	      }t        |d
i       }	|sHt        j                         }
|dk(  r|s|	j                  d      xs: |	j                  d      r#|	j                  dd      j                         d   ndxs d}|j                  |d|	t        j                  |
t        j                              }|j                          |||<   |||<   n^|r\||v rX||   }|j                  |d|	rd
|	ini t        j                  |
t        j                              }|j                          |||<   c y# t         $ r#}t"        j%                  d|        Y d}~d}~ww xY w)z+Process tool uses for an assistant message.rJ   Nr
   )_client_managed_runsparent_tool_use_idToolUseBlockidrR   unknown_toolinputTasksubagent_typedescriptionr   r   zunknown-agentchainrP   )rR   rS   rT   r$   toolz*Failed to create client-managed tool run: )rX   _hooksr   rW   rJ   rV   r;   r%   r|   splitrY   r   r\   r   r]   r^   r_   r`   ra   )r   r   r+   r   r   r   blocktool_use_id	tool_name
tool_inputr$   subagent_namesubagent_sessiontool_runre   s                  r   _handle_assistant_tool_useszSinstrument_claude_client.<locals>.TracedClaudeSDKClient._handle_assistant_tool_uses   s    3	*4!(.BD!I 9U;''>95U")%t"<K 'v~ FI!(!<J& !%J !F*3E 'NN?; / $.>>-#@ !+}b A G G I! L%)	/  / & ,/+;+;!.%,#-'/'='= *x||(	 ,< ,( )--/9I)+6<L,[9 ,0BFW0W+<=O+P(#3#@#@!*%+<FGZ#8B'/'='= *#+<<(	 $A $ !<D,[9m9Up ! UNN%OPQs#STTUs   )F5DF	F>F99F>c                  K   t         |          }i }i }| j                  r| j                  |d<   t        | d      r| j                  rt        | j                  d      r| j                  j
                  r| j                  j
                  }t        |t              r||d<   nSt        |t              rC|j                  d      dk(  r*d|j                  dd       }d	|v r|d
|d	    z  }||d<   n||d<   dD ]7  }t        | j                  |      st        | j                  |      }|3|||<   9 t        t        d||      4 d{   }t        |       t        | j                        }	g }
i }	 |2 3 d{   }t!        |      j"                  }|dk(  rit        |dd      }|r|j                  |      nd}|	j%                  || j                  |
|      }|r|
j'                  |       | j)                  |||       n|dk(  rt        |d      rt+        |j,                        }t        |t.              rh|rft        |d   t              rS|d   j                  d      dk(  r<|D ]6  }|
j'                  d|j                  dd      |j                  d      d       8 n|
j'                  |dd       |	j1                          n|dk(  rt        |d      rCt3        |      }t        |d      r|j4                  |j4                  |d<   |	j7                  |       t        |d d      t        |d!d      t        |d"d      t        |d#d      t        |d$d      d%j9                         D ci c]
  \  }}||| }}}|r|j:                  j=                  |       | )7 U7 (c c}}w 6 |j?                  |
r|
d&   nd'       n$# t@        $ r tB        jE                  d(       Y nw xY w|	jG                          tI                tK                n)# |	jG                          tI                tK                w xY wddd      d{  7   y# 1 d{  7  sw Y   yxY ww))z7Intercept message stream and record chain run activity.r   rg   system_promptsystemrV   presetzpreset: claude_codeappendz	
append: )rI   permission_mode	max_turnsNr   )rR   rS   rT   r2   rG   r   )r!   UserMessagerJ   r   tool_resultr   r   r   )rM   rJ   tool_call_iduserrL   ResultMessageusagetotal_cost_usd
total_cost	num_turns
session_idduration_msduration_api_msis_error)r   r   r   r   r   rF   )rU   z'Error while tracing Claude Agent stream)&r}   receive_responser~   rX   rg   r   
isinstancerB   rA   r|   rW   r	   TRACE_CHAIN_NAMEr   r   r   rV   r;   r,   r   r   r   rJ   r@   r/   r   r   r8   itemsr2   r6   r&   r_   r`   	exceptionr:   r   r   )r   rD   trace_inputstrace_metadatar   preset_textattrvalr+   tracker	collectedr   r   msg_typer   
llm_parentrJ   	flattenedr   r   kvr7   r   s                          r   r   zHinstrument_claude_client.<locals>.TracedClaudeSDKClient.receive_response  s    w/1H ,.LN ||)-X& tY'DLLDLL/:22$(LL$>$>M!-51>X.#M48(,,V4@"*=+<+<X}+U*V W (  (=8 +M(<S;T/U U5@L25BL2 F 7Dt||T2%dllD9?36N40	7 % #'	 h- h-
 #C('(8(8924	 57![-%- S" S"c#'9#5#5#'9918 #%942.
 $6 !2 5 56H I%) ' '.&;&; #T\\9Z '< 'G  ' ) 0 0 9 !<< # # 1
 &6&sI6,B3;;,O	$.y$$?(1(29Q<(F(1!(8(8(@M(Q 2; 	%*(1(8(88>;@99YPR;S@E		4AA2-.)*	%* %.$4$47@4:)*%& $335%8&sG4(I#(N %,C1A$B(+(:(:(F:=:L:LE,$7 ' 1 1% 8 29k41P29#|T2R3:3t3T7>(+->8& 18Z0N-" #(%'$$(Aq $%= !"1$D $  $ # 3 3D 9!	Ch-S"F$G &.h GGYIbMDGI  P$$%NOP MMO)+*, MMO)+*,Qh- h- h- h- h-s   DQQ)QNQ%Q1O3N(7N8N(;G+O&N"
5'OQN(" OPO$!P#O$$P'%Q&P22Q5Q QQQQQQc                 @   K   t         |           d {    | S 7 wr   )r}   
__aenter__)r   r   s    r   r   zBinstrument_claude_client.<locals>.TracedClaudeSDKClient.__aenter__  s"     '$&&&K 's   c                 :   K   t        |   |  d {    y 7 wr   )r}   	__aexit__)r   ry   r   s     r   r   zAinstrument_claude_client.<locals>.TracedClaudeSDKClient.__aexit__  s     '#T***s   )r"   TracedClaudeSDKClient)r;   r<   r=   r   r   r   rA   rB   r   r   r   r   r   __classcell__)r   s   @r   r   rx      s    	5# 	5 	5	8S 	8C 	8C 	8G	UG	U G	U  $CH~	G	U
 G	URP	-N39,E P	-d		+ 	+ 	+ 	+r   r   rC   )ru   r   s     r   instrument_claude_clientr      s    q+ q+f ! r   rH   )&r>   loggingr%   collections.abcr   r   r   typingr   r   langsmith.run_helpersr   r	   r   r   r   r   	_messagesr   r   r   _toolsr   r   	getLoggerr;   r`   r   rZ   r   r@   rA   rB   r?   tupler(   rt   r   rC   r   r   <module>r      s    2   * '   = Q Q 
 ?			8	$( &.$ .$j #' ."3i."." $sCx.!." 	."
 SM." 8DcN#Xc]23."b'?3 '?4 '?Tv!S v!S v!r   