
    jKj1                        d Z ddlmZ ddlmZmZ ddlmZmZmZm	Z	m
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mZ ddlmZ ddlmZmZm Z  dgZ!dZ" G d de      Z#	 	 	 	 	 	 	 	 ddZ$ddZ%ddZ&y)ur  ``PostHogMCP`` — a posthog ``Client`` subclass with first-class MCP analytics,
for custom dispatchers (Hono/edge/HTTP) where there is no ``Server``/``FastMCP``
to wrap. The host resolves identity + context per request and calls the capture
methods directly. MCP events flow through the same sanitize -> truncate ->
``$exception`` fan-out pipeline as ``instrument()``.
    )annotations)datetimetimezone)AnyDictListOptionalUnion)Client   )add_context_parameter_to_schemaget_context_descriptionis_context_enabled)MCPAnalyticsEventType)capture_exception)drain_pending_syncfire_and_forget)McpCaptureOptionsMcpEventSink)build_report_missing_descriptor)
JsonRecordMCPAnalyticsContextOptionsPreparedToolCall
PostHogMCPget_more_toolsc                      e Zd ZdZ	 	 d	 	 	 	 	 	 	 	 	 d fdZdd fdZd fdZdddddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZdddddddddddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd
Zddddddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	ddddddddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ
	 	 d	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 d dZ	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d!dZd"dZd#dZ xZS )$r   a"  A drop-in posthog ``Client`` with ``capture_tool_call`` / ``capture_initialize``
    / ``capture_tools_list`` / ``capture_missing_capability`` plus ``prepare_tool_list``
    and ``prepare_tool_call`` helpers. ``capture``, ``flush``, ``shutdown``, feature
    flags, etc. all work unchanged.Nc                r    t        |   |fi | t        |       | _        |xs t        | _        || _        y N)super__init__r   	_mcp_sink_GET_MORE_TOOLS_NAME_missing_capability_tool_name_mcp_exception_autocapture)selfapi_keymissing_capability_tool_namemcp_exception_autocapturekwargs	__class__s        h/Users/ahmed/devFolder/Ultron/claude-voice/.venv/lib/python3.12/site-packages/posthog/mcp/posthog_mcp.pyr    zPostHogMCP.__init__.   s?     	+F+%d+(@,@ 	* +D'    c                <    t        |       t        | 	  |      S )zDrain in-flight MCP captures scheduled on the background loop, then flush
        the underlying client. The capture methods are fire-and-forget on a sync host,
        so without this drain a trailing event could still be in flight at flush time.)timeout)timeout_seconds)r   r   flush)r%   r/   r*   s     r+   r0   zPostHogMCP.flushA   s     	?3w}_}==r,   c                4    t                t        | 	         S )zCDrain in-flight MCP captures, then shut the underlying client down.)r   r   shutdown)r%   r*   s    r+   r2   zPostHogMCP.shutdownH   s    w!!r,   F)intentintent_source
parametersresponseduration_msis_errorerrorcategorytool_descriptiondistinct_id
session_idset_propertiesgroups
properties	timestampc          	         | j                  t        j                  ||||||      }||d<   |
|d<   |	|d<   ||d<   ||d<   ||d<   ||d<   t        |||       |rt	        ||nd	| d
      |d<   | j                  |       y)zPCapture a tool invocation. Emits ``$mcp_tool_call`` (+ ``$exception`` on error).resource_namer;   tool_categoryr5   r6   durationr8   NzTool z returned an errorr9   )_base_eventr   MCP_TOOLS_CALL_apply_intentr   _emit)r%   	tool_namer3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   events                     r+   capture_tool_callzPostHogMCP.capture_tool_callO   s    *   !00
 "+o$4 !!)o(l$j'j$jeV]3.*%	{BT0UE'N 	

5r,   )client_nameclient_versionr5   r6   r7   r<   r=   r>   r?   r@   rA   c          	         | j                  t        j                  ||||	|
|      }||d<   ||d<   ||d<   ||d<   ||d<   | j                  |       y)z<Capture the connection handshake. Emits ``$mcp_initialize``.rM   rN   r5   r6   rE   N)rF   r   MCP_INITIALIZErI   )r%   rM   rN   r5   r6   r7   r<   r=   r>   r?   r@   rA   rK   s                r+   capture_initializezPostHogMCP.capture_initialize{   sp        !00
  +m"0(l$j'j

5r,   )
tool_namesr5   r6   r7   r8   r9   r<   r=   r>   r?   r@   rA   c          	         | j                  t        j                  |||	|
||      }||d<   ||d<   ||d<   ||d<   ||d<   |rt        ||nd      |d<   | j	                  |       y)	zCapture a ``tools/list`` response. Emits ``$mcp_tools_list`` with the
        advertised tool names (``$mcp_listed_tool_names``).listed_tool_namesr5   r6   rE   r8   Nztools/list failedr9   )rF   r   MCP_TOOLS_LISTr   rI   )r%   rR   r5   r6   r7   r8   r9   r<   r=   r>   r?   r@   rA   rK   s                 r+   capture_tools_listzPostHogMCP.capture_tools_list   s    $   !00
 &0!"(l$j'j$j.*0CE'N 	

5r,   )contextr5   r<   r=   r>   r?   r@   rA   c          	         | j                  t        j                  ||||||      }	| j                  |	d<   ||	d<   t	        |	|d       | j                  |	       y)zCapture a ``get_more_tools`` call as a missing-capability report. Emits
        ``$mcp_missing_capability`` with the agent's description as ``$mcp_intent``.rC   r5   context_parameterN)rF   r   MCP_MISSING_CAPABILITYr#   rH   rI   )
r%   rW   r5   r<   r=   r>   r?   r@   rA   rK   s
             r+   capture_missing_capabilityz%PostHogMCP.capture_missing_capability   sd       !88
 "&!C!Co(leW&9:

5r,   c                    t        |      r+t        |      }|D cg c]  } j                  ||       }}nt        |      }|r8t	         fd|D              s$|j                  t         j                               |S c c}w )a&  Inject the ``context`` argument into every tool so agents state their
        intent (captured as ``$mcp_intent``), and optionally append the
        ``get_more_tools`` virtual tool (``report_missing=True``). Returns a new
        list; dict tools are copied, tool objects are mutated in place.c              3  N   K   | ]  }t        |      j                  k(    y wr   )
_tool_namer#   ).0tr%   s     r+   	<genexpr>z/PostHogMCP.prepare_tool_list.<locals>.<genexpr>   s$      &
IQAJqMT???s   "%)r   r   _inject_contextlistanyappendr   r#   )r%   toolsrW   report_missingdescriptiontoolprepareds   `      r+   prepare_tool_listzPostHogMCP.prepare_tool_list   s     g&1':KLQRED,,T;?EHRE{H# &
IQ&
 #
 OO/0R0RS  Ss   A?c                    |xs i j                  d      }t        |t              r |j                         r|j                         nd}t	        t        |      ||rdnd|| j                  k(        S )zPull the agent's intent off the injected ``context`` argument, strip
        ``context`` from the arguments, and flag the ``get_more_tools`` virtual tool.rW   NrY   )argsr3   r4   is_missing_capability)get
isinstancestrstripr   _strip_contextr#   )r%   namerm   raw_contextr3   s        r+   prepare_tool_callzPostHogMCP.prepare_tool_call   su    
 zr&&y1 +s+0A0A0C  	
  %17-T"&$*L*L"L	
 	
r,   c                |    |||xs# t        j                  t        j                        ||d}|r||d<   |r||d<   |S )N)
event_typer=   rA   r@   r?   identify_actor_given_ididentify_actor_data)r   nowr   utc)	r%   rx   r<   r=   r>   r?   r@   rA   rK   s	            r+   rF   zPostHogMCP._base_event  sO     %$"@hll8<<&@$!
 /:E+,+9E'(r,   c                z    t        | j                        }t        | j                  j	                  ||             y )N)enable_exception_autocapture)r   r$   r   r!   capture)r%   rK   optionss      r+   rI   zPostHogMCP._emit"  s0    #)-)H)H
 	..ug>?r,   c                P   t        |t              rG|j                  dd      }|| j                  k(  r|S t	        |j                  d      ||      }i |d|iS t        |dd      }|| j                  k(  r|S t	        t        |dd       ||      }	 ||_        |S # t        $ r Y |S w xY w)Nrt   unknowninputSchema)rp   dictro   r#   r   getattrr   	Exception)r%   ri   rh   rt   
new_schemas        r+   rb   zPostHogMCP._inject_context)  s    dD!88FI.Dt9998'{J 7d6M:66tVY/4555K4D-.k

	)D   		s   B 	B%$B%)NT)
r&   rq   r'   Optional[str]r(   boolr)   r   returnNone)
   )r/   Optional[float]r   r   )r   r   )"rJ   rq   r3   r   r4   r   r5   r   r6   r   r7   r   r8   r   r9   r   r:   r   r;   r   r<   r   r=   r   r>   Optional[JsonRecord]r?   Optional[Dict[str, str]]r@   r   rA   Optional[datetime]r   r   )rM   r   rN   r   r5   r   r6   r   r7   r   r<   r   r=   r   r>   r   r?   r   r@   r   rA   r   r   r   )rR   zOptional[List[str]]r5   r   r6   r   r7   r   r8   r   r9   r   r<   r   r=   r   r>   r   r?   r   r@   r   rA   r   r   r   )rW   r   r5   r   r<   r   r=   r   r>   r   r?   r   r@   r   rA   r   r   r   )TF)rf   	List[Any]rW   z'Union[bool, MCPAnalyticsContextOptions]rg   r   r   r   r   )rt   rq   rm   r   r   r   )rx   rq   r<   r   r=   r   r>   r   r?   r   r@   r   rA   r   r   Dict[str, Any])rK   r   r   r   )ri   r   rh   r   r   r   )__name__
__module____qualname____doc__r    r0   r2   rL   rQ   rV   r[   rk   rv   rF   rI   rb   __classcell__)r*   s   @r+   r   r   (   s   ' 7;*.	DD '4D $(	D
 D 
D&>" !%'+'+"&*.%)$(/3+/+/(,%** 	*
 %* * * %* * *  * (* #* "* -*  )!*" )#*$ &%*& 
'*^ &*(,'+%)$(/3+/+/(, # &	
   % # " - ) ) & 
F +/'+%)$(/3+/+/(,$ ($ 	$
 $ %$ $ $ #$ "$ -$ )$ )$ &$ 
$R "&%)$(/3+/+/(,  	
 # " - ) ) & 
B <@$	 9 	
 
2 7;

3
	
( # "	
 - ) ) & 
.@r,   c                j    t        |t              r|j                         nd}|sy || d<   |xs d| d<   y )N user_intentrY   user_intent_source)rp   rq   rr   )rK   r3   sourcetrimmeds       r+   rH   rH   @  s;     !+63 7fllnRG"E-"("?,?E
r,   c                r    | rd| vr| S | j                         D ci c]  \  }}|dk7  s|| c}}S c c}}w )NrW   )items)rm   kvs      r+   rs   rs   J  s=    9D(!ZZ\<\TQQ)^AqD\<<<s   33c                ^    t        | t              r| j                  d      S t        | dd       S )Nrt   )rp   r   ro   r   )ri   s    r+   r^   r^   P  s*    $xx4&&r,   N)rK   r   r3   r   r   r   r   r   )rm   r   r   r   )ri   r   r   r   )'r   
__future__r   r   r   typingr   r   r   r	   r
   posthog.clientr   _context_parametersr   r   r   _event_typesr   _exceptionsr   _instrumentationr   r   _sinkr   r   rf   r   typesr   r   r   __all__r"   r   rH   rs   r^    r,   r+   <module>r      s   
 # ' 3 3 ! 
 0 * A 2 2  .' U Up@@#0@:G@	@='r,   