
    Ģ-i	
                     h    d dl Z d dlZd dlZd dlmZmZmZ  ej                  e      Z	 G d d      Z
y)    N)OptionalDictAnyc                       e Zd ZdZededeeeef      fd       Z	ededeeeef      fd       Z
ededefd       Zededefd       Zededefd	       Zy
)ModelJSONParserz
    A JSON extractor for LLM responses.
    Handles:
    - Backtick fenced blocks
    - Extra text before/after JSON
    - Loose/truncated JSON
    - Trailing commas
    - Missing quotes around keys
    response_textreturnc                    | rt        | t              syt        j                  |       }|r|S t        j	                  |       }t        j                  |      }|r|S t        j                  |       }t        j                  |      }|r|S t        j                  |       }t        j                  |      }|r|S t        j                  d       y)z|
        Main public method.
        Tries multiple parsing strategies safely.
        Returns Python dict or None.
        Nz;ModelJSONParser: Failed to parse JSON after all strategies.)	
isinstancestrr   	_try_json_extract_fenced_json_extract_json_object_clean_jsonloggerwarning)r   datafenced	extractedcleaneds        K/var/www/html/dp2/backend_v2.1/server/apps/calls/services/json_sanitizer.pyparsezModelJSONParser.parse   s     J}c$B((7K 55mD((0K#88G	((3K!--m<((1KTU    textc                 L    	 t        j                  |       S # t        $ r Y yw xY w)zSafe JSON.parse wrapper.N)jsonloads	Exception)r   s    r   r   zModelJSONParser._try_json5   s(    	::d## 		s    	##c                     d}t        j                  || t         j                  t         j                  z        }|r|j	                  d      j                         S | S )zH
        Extracts content inside ```json ... ``` or ``` ... ```
        z```(?:json)?\s*(.*?)```flags   )researchDOTALL
IGNORECASEgroupstrip)r   patternmatchs      r   r   z$ModelJSONParser._extract_fenced_json=   sF    
 -		'4ryy2==/HI).u{{1~##%8D8r   c                 x    t        j                  d| t         j                        }|r|j                  d      S | S )z0
        Extract the first {...} block.
        z\{.*\}r    r   )r#   r$   r%   r'   )r   r*   s     r   r   z$ModelJSONParser._extract_json_objectF   s/    
 		)T;!&u{{1~0D0r   c                     | }|j                  dd      j                  dd      }t        j                  dd|      }d|v r*d|v r&||j                  d      |j	                  d      dz    }|j                         S )	z:
        Attempt to fix common LLM JSON glitches.
        z```json z```z,\s*([\]}])z\1{}r"   )replacer#   subfindrfindr(   )r   r   s     r   r   zModelJSONParser._clean_jsonN   st    
 //)R088C&&8'>cWngll3/s1Ca1GHG}}r   N)__name__
__module____qualname____doc__staticmethodr   r   r   r   r   r   r   r   r    r   r   r   r   	   s     S Xd38n%=  @  c3h 8   93 93 9 9 13 13 1 1 # #  r   r   )r   r#   loggingtypingr   r   r   	getLoggerr4   r   r   r9   r   r   <module>r=      s2     	  & &			8	$S Sr   