
    yj                     r    d Z ddlmZmZ dZdedefdZdedefdZdefd	Zd
edefdZdedededefdZ	dS )z
Shared formatting utility functions for both dialectic and deriver modules.

This module contains helper functions for processing observations, formatting context,
handling temporal metadata, and string escaping for the reasoning system.
    )datetimetimezone\textreturnc                     |                      t          t          t          z                                  dt          dz                                  dt          dz             S )aH  
    Escape SQL ILIKE/LIKE pattern special characters in user-provided text.

    SQL LIKE/ILIKE patterns treat '%' as "match any sequence" and '_' as
    "match any single character". Without escaping, a user searching for
    "100%" would match "100" followed by anything, not the literal "100%".

    This function escapes these wildcards so user input is treated literally.
    The escape character itself (backslash) is also escaped.

    Args:
        text: User-provided search text that may contain %, _, or backslash

    Returns:
        Escaped text safe for use in ILIKE patterns. Use with escape='\' parameter.

    Example:
        >>> escape_ilike_pattern("100%")
        '100\%'
        >>> escape_ilike_pattern("file_name")
        'file\_name'
        >>> escape_ilike_pattern("path\to\file")
        'path\\to\\file'
    %_)replaceILIKE_ESCAPE_CHAR)r   s    </DATA/AppData/hermes/projects/honcho/src/utils/formatting.pyescape_ilike_patternr      sL    4 	&(9<M(MNN	'#-	.	.	'#-	.	.    dtc                 4   | j          |                     t          j                  } | j         t          j        k    r|                     t          j                  } |                     d          } |                                                     dd          S )a,  
    Format datetime to ISO 8601 string with Z suffix for UTC timezone.

    This ensures consistent datetime formatting across the entire backend,
    using the Z format which is the ISO 8601 standard for UTC and matches
    Pydantic's JSON serialization behavior.

    Args:
        dt: datetime object (should be timezone-aware)

    Returns:
        ISO 8601 formatted string with Z suffix for UTC

    Example:
        >>> dt = datetime(2023, 1, 1, 12, 0, 0, tzinfo=timezone.utc)
        >>> format_datetime_utc(dt)
        '2023-01-01T12:00:00Z'
    Ntzinfor   )microsecond+00:00Z)r   r   r   utc
astimezone	isoformat)r   s    r   format_datetime_utcr   -   sz    & 
yZZx|Z,, 
yHL  ]]8<(( 
	"	"B <<>>!!(C000r   c                  X    t          t          j        t          j                            S )z
    Get current UTC time as ISO 8601 string with Z suffix.
    Removes subsecond precision.

    Returns:
        Current UTC time in ISO 8601 format with Z suffix

    Example:
        >>> utc_now_iso()
        '2023-01-01T12:34:56Z'
    )r   r   nowr   r    r   r   utc_now_isor   O   s     x|HL99:::r   
iso_stringc                    | st          d          t          |           } d| v sd| v sd| v rt          d          t          d | D                       rt          d          |                                 } | st          d          |                     d	          r| d
d         dz   } 	 t          j        |           }|j         |                    t          j
                  }|S # t           $ r}t          d|           |d
}~ww xY w)a  
    Parse ISO 8601 datetime string, handling various timezone formats.

    This function properly handles Z suffix, timezone offsets, and naive timestamps.
    It validates input and always returns a timezone-aware datetime object.

    Args:
        iso_string: ISO 8601 formatted datetime string

    Returns:
        datetime object with timezone information

    Raises:
        ValueError: If the input string is invalid or contains suspicious content

    Example:
        >>> parse_datetime_iso('2023-01-01T12:00:00Z')
        datetime.datetime(2023, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)
        >>> parse_datetime_iso('2023-01-01T12:00:00+05:00')
        datetime.datetime(2023, 1, 1, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=18000)))
    z)Invalid input: must be a non-empty string 
z1Invalid input: contains null bytes or line breaksc              3   D   K   | ]}t          |          d k     o|dvV  dS )    	N)ord).0cs     r   	<genexpr>z%parse_datetime_iso.<locals>.<genexpr>   s5      
=
=Q3q66B;(1D=
=
=
=
=
=
=r   z0Invalid input: contains non-printable charactersz/Invalid input: empty after stripping whitespace)r   zNr   r   z"Invalid ISO 8601 datetime format: )
ValueErrorstranystripendswithr   fromisoformatr   r   r   r   )r   resultes      r   parse_datetime_isor5   ^   sS   .  FDEEEZJ tz11TZ5G5GLMMM 
=
=*
=
=
=== MKLLL !!##J LJKKK :&& 0_x/

J'
33 = ^^8<^88F J J JAaAABBIJs   ,<C) )
D3DDnew_turncurrent_timespeakerc                 @    |                     d          }| d| d|  S )a  
    Format new turn message with optional timestamp.

    Args:
        new_turn: The message content
        current_time: Message timestamp
        speaker: The speaker's name

    Returns:
        Formatted string like "2023-05-08 13:56:00 speaker: hello"
    z%Y-%m-%d %H:%M:%S z: )strftime)r6   r7   r8   current_time_strs       r   format_new_turn_with_timestampr=      s5     $,,-@AA6666H666r   N)
__doc__r   r   r   r.   r   r   r   r5   r=   r   r   r   <module>r?      s     ( ' ' ' ' ' ' ' s s    @1H 1 1 1 1 1D;S ; ; ; ;7J3 7J8 7J 7J 7J 7Jt77!)74777 7 7 7 7 7r   