
    6i                    H    d Z ddlmZ ddlmZ ddlmZ d	dZ G d d      Zy)
a+  
JSON Completeness Tracker for Partial Streaming.

Tracks which parts of accumulated JSON are "closed" (complete) vs "open" (incomplete).
Uses jiter for parsing and a simple heuristic: if a value has a next sibling,
it must be complete (because jiter had to finish parsing it to find the next one).
    )annotations)Any)	from_jsonc                |    | r| j                         sy	 t        | j                                y# t        $ r Y yw xY w)z
    Check if a JSON string represents a complete structure.

    Uses jiter in strict mode - parsing fails if JSON is incomplete.
    FT)stripr   encode
ValueError)json_strs    f/root/.openclaw/workspace/visionaryfx/venv/lib/python3.12/site-packages/instructor/dsl/json_tracker.pyis_json_completer      s<     8>>+(//#$ s   / 	;;c                  H    e Zd ZdZd
dZddZddZddZddZddZ	ddZ
y	)JsonCompletenessa0  
    Track completeness of JSON structures during streaming.

    Uses a simple heuristic: if a value has a next sibling in the parsed
    structure, it must be complete. For the last sibling, we don't know
    until the parent completes - but that's fine because parent validation
    will cover it.

    Example:
        tracker = JsonCompleteness()

        # Incomplete - missing closing brace
        tracker.analyze('{"name": "Alice", "address": {"city": "NY')
        tracker.is_path_complete("")  # False - root incomplete
        tracker.is_path_complete("name")  # True - has next sibling "address"
        tracker.is_path_complete("address")  # False - last sibling, unknown

        # Complete
        tracker.analyze('{"name": "Alice"}')
        tracker.is_path_complete("")  # True - root complete
    c                "    t               | _        y )N)set_complete_pathsselfs    r   __init__zJsonCompleteness.__init__6   s    ),    c                <   t               | _        |r|j                         sy	 t        |j	                               }| j                  |d       y# t        $ r Y nw xY w	 t        |j	                         d      }n# t        $ r Y yw xY w| j                  |d       y)z>Analyze a JSON string and determine completeness of each path.N ztrailing-strings)partial_mode)r   r   r   r   r   	_mark_allr	   _check_siblings)r   r
   parseds      r   analyzezJsonCompleteness.analyze9   s    "ux~~/	x01FNN62& 			x0?QRF 		 	VR(s#   +A 	AA A< <	BBc                >   | j                   j                  |       t        |t              r6|j	                         D ]"  \  }}|r| d| n|}| j                  ||       $ yt        |t              r,t        |      D ]  \  }}| j                  || d| d        yy)z3Recursively mark path and all children as complete..[]N)r   add
isinstancedictitemsr   list	enumerate)r   datapathkeyvalue
child_pathiitems           r   r   zJsonCompleteness._mark_allP   s      &dD!"jjl 2
U04vQse_#
uj12 d#$T? 54tvQqc^45 $r   c                   t        |t              rtt        |j                               }t	        |      D ]L  \  }}|r| d| n|}|t        |      dz
  k  r| j                  ||   |       8| j                  ||   |       N yt        |t              rRt	        |      D ]C  \  }}| d| d}|t        |      dz
  k  r| j                  ||       2| j                  ||       E yy)z
        Check completeness using sibling heuristic.

        If a value has a next sibling, it's complete (jiter had to finish
        parsing it to find the next sibling). Last sibling is unknown.
        r      r   r    N)r"   r#   r%   keysr&   lenr   r   )r   r'   r(   r0   r,   r)   r+   r-   s           r   r   z JsonCompleteness._check_siblings[   s     dD!		$D#D/ @304vQse_#
s4y1}$NN49j9 ((cJ?@ d#$T? ;4 $vQqc^
s4y1}$NN44 ((z:; $r   c                    || j                   v S )a4  
        Check if the sub-structure at the given path is complete.

        Args:
            path: Dot-separated path (e.g., "user.address.city", "items[0]")
                  Use "" for root object.

        Returns:
            True if the structure at path is complete (closed), False otherwise.
        r   )r   r(   s     r   is_path_completez!JsonCompleteness.is_path_completew   s     t++++r   c                6    | j                   j                         S )z#Return all paths that are complete.)r   copyr   s    r   get_complete_pathsz#JsonCompleteness.get_complete_paths   s    ##((**r   c                    d| j                   v S )z-Check if the root JSON structure is complete.r   r3   r   s    r   is_root_completez!JsonCompleteness.is_root_complete   s    T))))r   N)returnNone)r
   strr:   r;   )r'   r   r(   r<   r:   r;   )r(   r<   r:   bool)r:   zset[str])r:   r=   )__name__
__module____qualname____doc__r   r   r   r   r4   r7   r9    r   r   r   r      s*    ,/).	5;8,+*r   r   N)r
   r<   r:   r=   )	rA   
__future__r   typingr   jiterr   r   r   rB   r   r   <module>rF      s&    #  k* k*r   