
    k7ix"                    x    S SK Jr  S SKJr  SS jr   S         S	S jjr    S
           SS jjrg)    )annotations)defaultdictc                    U R                  S0 5      nUR                  US5      nUc  U $ X S'   XR                  S/ 5      ;   a/  U S   R                  U5        U S   (       d  U R                  S5        U $ )zoReturn a new schema with *param* removed from `properties`, `required`,
and (if no longer referenced) `$defs`.

propertiesNrequired)getpopremove)schemaparampropsremoveds       W/home/james-whalen/.local/lib/python3.13/site-packages/fastmcp/utilities/json_schema.py_prune_paramr      su     JJ|R(Eiit$G !<

:r**z!!%(j!JJz"M    c                  ^^^^^^	^
 T(       d  T(       d	  T(       d  U $ [        5       m	[        [        5      mU R                  S5      n   S         S	UUUUU	U
4S jjjm
T
" U SS9  T(       a  U(       a  UR	                  5        H  u  pVT
" XeS9  M     S
SUUU	4S jjjm[        UR                  5       5       H#  nT" U5      (       a  M  UR                  U5        M%     U(       d  U R                  SS5        U $ )a  
Optimize JSON schemas in a single traversal for better performance.

This function combines three schema cleanup operations that would normally require
separate tree traversals:

1. **Remove unused definitions** (prune_defs): Finds and removes `$defs` entries
   that aren't referenced anywhere in the schema, reducing schema size.

2. **Remove titles** (prune_titles): Strips `title` fields throughout the schema
   to reduce verbosity while preserving functional information.

3. **Remove restrictive additionalProperties** (prune_additional_properties):
   Removes `"additionalProperties": false` constraints to make schemas more flexible.

**Performance Benefits:**
- Single tree traversal instead of multiple passes (2-3x faster)
- Immutable design prevents shared reference bugs
- Early termination prevents runaway recursion on deeply nested schemas

**Algorithm Overview:**
1. Traverse main schema, collecting $ref references and applying cleanups
2. Traverse $defs section to map inter-definition dependencies
3. Remove unused definitions based on reference analysis

Args:
    schema: JSON schema dict to optimize (not modified)
    prune_titles: Remove title fields for cleaner output
    prune_additional_properties: Remove "additionalProperties": false constraints
    prune_defs: Remove unused $defs entries to reduce size

Returns:
    A new optimized schema dict

Example:
    >>> schema = {
    ...     "type": "object",
    ...     "title": "MySchema",
    ...     "additionalProperties": False,
    ...     "$defs": {"UnusedDef": {"type": "string"}}
    ... }
    >>> result = _single_pass_optimize(schema, prune_titles=True, prune_defs=True)
    >>> # Result: {"type": "object", "additionalProperties": False}
$defsNc                *  >^  US:  a  g[        T [        5      (       GaK  T(       a}  T R                  S5      n[        U[        5      (       aW  UR	                  S5      (       aA  UR                  S5      S   nU(       a  T	U   R                  U5        OTR                  U5        T(       a1  ST ;   a+  [        U 4S jS	 5       5      (       a  T R                  S5        T
(       a%  T R                  S
5      SL a  T R                  S
5        T R                  5        HN  u  pgU(       a  US:X  a  M  US;   a*  [        U[        5      (       a  U H  nT" XUS-   S9  M     MD  T" XqUS-   S9  MP     g[        T [        5      (       a  T  H  nT" XUS-   S9  M     gg)zATraverse schema tree, collecting $ref info and applying cleanups.2   N$refz#/$defs//titlec              3  .   >#    U  H
  nUT;   v   M     g 7fN ).0knodes     r   	<genexpr>D_single_pass_optimize.<locals>.traverse_and_clean.<locals>.<genexpr>u   s       	 I	s   )typer   r   itemsallOfoneOfanyOfr   additionalPropertiesFr   )r$   r%   r&      )depth)
isinstancedictr   str
startswithsplitappendaddanyr	   r#   list)r   current_def_nameskip_defs_sectionr)   refreferenced_defkeyvalueitemdef_dependenciesprune_additional_properties
prune_defsprune_titles	root_refstraverse_and_cleans   `        r   r?   1_single_pass_optimize.<locals>.traverse_and_cleanX   sd    2:dD!!hhv&c3''CNN:,F,F%(YYs^B%7N'(8??@PQ "n5 4 	   HHW% ,HH34=/0 #jjl
$ 55*UD:Q:Q %*4QRS !& 'ueaiP + d##"4K  $r   T)r4   )r3   c                   > U T;   a  gTR                  U / 5      nU(       a7  Uc
  [        5       nX;   a  gX1-  nU H  nX1;  d  M
  T" X15      (       d  M    g   g)z<Check if a definition is used, handling circular references.TF)r   set)def_namevisitingreferencing_defsreferencing_defr:   is_def_usedr>   s       r   rG   *_single_pass_optimize.<locals>.is_def_used   ss    9$  033HbA#"uH ' #j0 (8O&6;'< <  $	 (8 r   )NFr   )
r   objectr3   z
str | Noner4   boolr)   intreturnNoner   )rC   r,   rD   zset[str] | NonerL   rJ   )rB   r   r2   r   r#   keysr	   )r   r=   r;   r<   defsrC   
def_schemar:   rG   r>   r?   s    ```   @@@@r   _single_pass_optimizerQ      s
   d ,*E %I4?5 ::gD (,"'	@L@L$@L  @L 	@L
 
@L @LF v6 d$(JJL HzE %1	 	4 TYY[)Hx((" *
 JJw%Mr   Nc                ~    U=(       d    /  H  n[        XS9n M     U(       d  U(       d  U(       a  [        U UUUS9n U $ )aa  
Remove the given parameters from the schema.

Args:
    schema: The schema to compress
    prune_params: List of parameter names to remove from properties
    prune_defs: Whether to remove unused definitions
    prune_additional_properties: Whether to remove additionalProperties: false
    prune_titles: Whether to remove title fields from the schema
)r   )r=   r;   r<   )r   rQ   )r   prune_paramsr<   r;   r=   r   s         r   compress_schemarT      sG    $ ##f2 $ 2j&%(C!	
 Mr   )r   r+   r   r,   rL   r+   )FFT)
r   r+   r=   rJ   r;   rJ   r<   rJ   rL   r+   )NTTF)r   r+   rS   zlist[str] | Noner<   rJ   r;   rJ   r=   rJ   rL   r+   )
__future__r   collectionsr   r   rQ   rT   r   r   r   <module>rW      s    " #. (-	jjj "&j 	j
 
j^ &*(,"  "&	
  
r   