§
    ØŽ’j§0  ã                   óð  — U d Z ddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
m
Z
 ddlmZmZ ddlmZ ddlmZ d„ aeg ef         ed	<   d
„ aeg ef         ed<   deg ef         ddfd„Zdeg ef         ddfd„Zdefd„Zdefd„Zdedefd„Z	 d+dededz  defd„Zd,dedefd„Zdedefd„Zdedededefd„Z 	 d-d ed!e!defd"„Z"d#edefd$„Z#dedefd%„Z$d#ede!fd&„Z%d'e!de!fd(„Z&d)e'defd*„Z(dS ).z,The common utilities for agentscope library.é    N)Údatetime)ÚAnyÚCallableé   )Úlogger)ÚToolJSONDecodeErrorc                  ó2   — t          j        ¦   «         j        S ©N)ÚuuidÚuuid4Úhex© ó    úGC:\Projects\DSCons\.venv\Lib\site-packages\agentscope\_utils\_common.pyú<lambda>r      s   € ­¬©¬Ô)9€ r   Ú_id_factoryc                  óL   — t          j        ¦   «                              ¦   «         S r
   )r   ÚnowÚ	isoformatr   r   r   r   r      s   € µ´±´×0HÒ0HÑ0JÔ0J€ r   Ú_timestamp_factoryÚfactoryÚreturnc                 óp   — t          | ¦  «        s$t          dt          | ¦  «        j        › �¦  «        ‚| adS )ae  Override the global ID factory used by all AgentScope entities.

    Entity IDs default to ``uuid.uuid4().hex``. Call this once at
    startup to substitute a different strategy.

    .. note::
        Security-sensitive tokens (gateway tokens, Redis lock tokens)
        are **not** affected and always use ``uuid.uuid4().hex``.

    Args:
        factory (`Callable[[], str]`):
            A no-arg callable returning a string ID.

    Raises:
        TypeError: If ``factory`` is not callable.

    Example:
        >>> from agentscope import set_id_factory
        >>> set_id_factory(lambda: uuid7().hex)
    ú factory must be a callable, got N)ÚcallableÚ	TypeErrorÚtypeÚ__name__r   ©r   s    r   Úset_id_factoryr       sE   € õ* �GÑÔð 
ÝØG­t°G©}¬}Ô/EÐGÐGñ
ô 
ð 	
ð €K€K€Kr   c                 óp   — t          | ¦  «        s$t          dt          | ¦  «        j        › �¦  «        ‚| adS )zòOverride the global timestamp factory used by all AgentScope entities.

    Args:
        factory (`Callable[[], str]`):
            A no-arg callable returning a string ID.

    Raises:
        TypeError: If ``factory`` is not callable.
    r   N)r   r   r   r   r   r   s    r   Úset_timestamp_factoryr"   4   sH   € õ �GÑÔð 
ÝØG­t°G©}¬}Ô/EÐGÐGñ
ô 
ð 	
ð !ÐÐÐr   c                  ó   — t          ¦   «         S )z:Generate an ID string using the current global ID factory.)r   r   r   r   Ú_generate_idr$   F   s   € å‰=Œ=Ðr   c                  ó   — t          ¦   «         S )zKGenerate a timestamp string using the current global
    timestamp factory.)r   r   r   r   Ú_generate_timestampr&   K   s   € õ ÑÔÐr   Úpathc                 óz   — t           j                             t           j                             | ¦  «        ¦  «        S )z=Expand user-home shorthand and return an absolute local path.)Úosr'   ÚabspathÚ
expanduser)r'   s    r   Ú_normalize_local_pathr,   Q   s&   € åŒ7�?Š?�2œ7×-Ò-¨dÑ3Ô3Ñ4Ô4Ð4r   Újson_strÚschemac           
      ó2  — 	 t          j        | ¦  «        }t          |t          ¦  «        r|S dt	          |¦  «        › d�}n/# t           j        $ r}dt          |¦  «        › d�}Y d}~nd}~ww xY w	 ddlm}  || d|¬	¦  «        }t          j        |¦  «        }t          |t          ¦  «        r|S n# t          $ r Y nw xY wt          | ¦  «        d
k    r| dd…         dz   | dd…         z   }d}n| }d}t          d|› d|› dt          |¦  «        › d�¦  «        ‚)a§  The given json_str maybe incomplete, e.g. '{"key', so we need to
    repair and load it into a Python object.

    .. note::
        This function is currently only used for parsing the streaming output
        of the argument field in `tool_use`, so the parsed result must be a
        dict.

    Args:
        json_str (`str`):
            The JSON string to parse, which may be incomplete or malformed.
        schema (`dict`, optional):
            An optional JSON schema to guide the repair process.

    Returns:
        `dict`:
            A dictionary parsed from the JSON string after repair attempts.
            Returns an empty dict if all repair attempts fail.
    z.Error: Your argument string is decoded into a z' object, but a dict object is expected!z}Error: When decoding your tool arguments from JSON format to a Python dictionary, a JSONDecodeError was raised with message: ú.Nr   )Úrepair_jsonT)Ústream_stabler.   éÈ   éd   z
[TRUNCATE]iœÿÿÿzm(Because the JSON string is too long, a truncated label "[TRUNCATE]" is used here to indicate the truncation)Ú z<system-reminder>z?

Your argument string is decoded by the following code snippetz/:
```python
import json

your_tool_arguments = zn
json.loads(your_tool_arguments)
```

**You should recorrect the arguments in JSON format.**</system-reminder>)ÚjsonÚloadsÚ
isinstanceÚdictr   ÚJSONDecodeErrorÚstrÚjson_repairr1   Ú	ExceptionÚlenr   Úrepr)	r-   r.   ÚresÚerror_messageÚer1   ÚrepairedÚerror_json_strÚellipsis_hints	            r   Ú_json_loads_with_repairrF   V   s»  € ð.
åŒj˜Ñ"Ô"ˆÝ�c�4Ñ Ô ð 	ØˆJð6½TÀ#¹Y¼Yð 6ð 6ð 6ð 	ˆøõ Ôð 
ð 
ð 
ð"å˜A™œð"ð "ð "ð 	ˆˆˆˆˆøøøøð
øøøðà+Ð+Ð+Ð+Ð+Ð+à�;˜x°tÀFÐKÑKÔKˆÝŒj˜Ñ"Ô"ˆÝ�c�4Ñ Ô ð 	ØˆJð	øõ ð ð ð ð 	ˆðøøøõ ˆ8�}„}�sÒÐØ! $ 3 $œ¨,Ñ6¸À$À%À%¼ÑHˆðDð 	ˆð
 "ˆØˆå
ð
	L˜mð 
	Lð 
	Là>Kð
	Lð 
	Lõ ˜NÑ+Ô+ð
	Lð 
	Lð 
	Lñô ð s.   ‚*A ­A ÁA-ÁA(Á(A-Á1>B1 Â1
B>Â=B>FÚadd_random_suffixc                 ó¾   — t          j        ¦   «                              d¦  «        dd…         }| r,|dt          j        d¦  «                             ¦   «         › �z  }|S )z@Get the current timestamp in the format YYYY-MM-DD HH:MM:SS.sss.z%Y-%m-%d %H:%M:%S.%fNéýÿÿÿÚ_é   )r   r   Ústrftimer)   Úurandomr   )rG   Ú	timestamps     r   Ú_get_timestamprO   §   sZ   € å”‘”×'Ò'Ð(>Ñ?Ô?ÀÀÀÔD€Iàð /àÐ.�œ A™œ×*Ò*Ñ,Ô,Ð.Ð.Ñ.ˆ	àÐr   Úfuncc              ƒ   óN  K  — t          j        | ¦  «        p�t          j        | ¦  «        p{t          | t          j        ¦  «        pat          | t          j        ¦  «        ot          j        | ¦  «        p3t          | t          j
        ¦  «        ot          | j        ¦  «        ƒ d{V —†S )z‚Check if the given function is an async function, including
    coroutine functions, async generators, and coroutine objects.
    N)ÚinspectÚiscoroutinefunctionÚisasyncgenfunctionr8   ÚtypesÚCoroutineTypeÚGeneratorTypeÚasyncioÚiscoroutineÚ	functoolsÚpartialÚ_is_async_funcrP   )rP   s    r   r\   r\   ²   s¨   è è € õ 	Ô# DÑ)Ô)ð 	,ÝÔ% dÑ+Ô+ð	,å�d�EÔ/Ñ0Ô0ð	,õ �d�EÔ/Ñ0Ô0ð &ÝÔ Ñ%Ô%ð		,õ
 �d�IÔ-Ñ.Ô.ð ,Ý  ¤Ñ+Ô+Ð+Ð+Ð+Ð+Ð+Ð+ðr   ÚargsÚkwargsc              �   ó\   K  — t          | ¦  «        ƒ d{V —†r | |i |¤Žƒ d{V —†S  | |i |¤ŽS )a¦  Execute an async or sync function based on its type.

    Args:
        func (`Callable`):
            The function to be executed, which can be either async or sync.
        *args (`Any`):
            Positional arguments to be passed to the function.
        **kwargs (`Any`):
            Keyword arguments to be passed to the function.

    Returns:
        `Any`:
            The result of the function execution.
    N)r\   )rP   r]   r^   s      r   Ú_execute_async_or_sync_funcr`   Â   sf   è è € õ( ˜DÑ!Ô!Ð!Ð!Ð!Ð!Ð!Ð!ð +Ø�T˜4Ð* 6Ð*Ð*Ð*Ð*Ð*Ð*Ð*Ð*Ð*àˆ4�Ð ˜Ð Ð Ð r   rK   ÚurlÚmax_retriesc           	      óÊ  — ddl }t          |¦  «        D ]º}	 |                     | ¦  «        }|                     ¦   «          |j                             d¦  «        c S # t          $ r1 t          j        |j        ¦  «                             d¦  «        cY c S t          $ r-}t          j        d| t          |¦  «        ¦  «         Y d}~Œ³d}~ww xY wt          d| › d|› d�¦  «        ‚)	zÊGet the bytes from a given URL.

    Args:
        url (`str`):
            The URL to fetch the bytes from.
        max_retries (`int`, defaults to `3`):
            The maximum number of retries.
    r   Núutf-8Úasciiz8Failed to fetch bytes from URL %s. Error %s. Retrying...z Failed to fetch bytes from URL `z` after z	 retries.)ÚrequestsÚrangeÚgetÚraise_for_statusÚcontentÚdecodeÚUnicodeDecodeErrorÚbase64Ú	b64encoder=   r   Úinfor;   ÚRuntimeError)ra   rb   rf   rJ   ÚresponserB   s         r   Ú_get_bytes_from_web_urlrr   Ü   s1  € ð €O€O€Oå�;ÑÔð ð ˆð	Ø—|’| CÑ(Ô(ˆHØ×%Ò%Ñ'Ô'Ð'ØÔ#×*Ò*¨7Ñ3Ô3Ð3Ð3Ð3øå!ð 	Fð 	Fð 	FÝÔ# HÔ$4Ñ5Ô5×<Ò<¸WÑEÔEÐEÐEÐEÐEÐEåð 	ð 	ð 	ÝŒKØJØÝ�A‘”ñô ð ð ð ð ð ð øøøøð	øøøõ ØN¨3ÐNÐN¸ÐNÐNÐNñô ð s   —AAÁ6CÂ	CÂ#CÃCÚtextc                 óZ   — t          t          j        t          j        | ¦  «        ¦  «        S )zíMap the given text to a deterministic UUID string.

    Args:
        text (`str`):
            The input text to be mapped to a UUID.

    Returns:
        `str`:
            A deterministic UUID string derived from the input text.
    )r;   r   Úuuid3ÚNAMESPACE_DNS©rs   s    r   Ú_map_text_to_uuidrx   ÿ   s!   € õ �tŒz�$Ô,¨dÑ3Ô3Ñ4Ô4Ð4r   c                 óŒ  ‡‡— t          |                      d¦  «        t          ¦  «        p't          |                      d¦  «        t          ¦  «        }|s| S t          j        | ¦  «        } i Št          |                      d¦  «        t          ¦  «        r(‰                     |                      d¦  «        ¦  «         t          |                      d¦  «        t          ¦  «        r(‰                     |                      d¦  «        ¦  «         ‰s| S t          ¦   «         fdt          dt          dt          fˆˆfd„Š ‰| ¦  «        S )aD  Flatten a JSON schema by resolving all local ``$ref`` references.

    Some LLM providers (e.g. Gemini, GLM-5.x via OpenCode Go) cannot
    process ``$defs`` / ``$ref`` patterns in tool parameter schemas.
    When Pydantic generates schemas for complex nested types it emits a
    ``$defs`` block (or the legacy ``definitions`` block) and refers to
    it with ``{"$ref": "#/$defs/TypeName"}``.

    This function resolves every such reference by substituting the full
    definition inline, then drops the ``$defs`` / ``definitions``
    sections so the output is a flat, self-contained schema.

    Circular references are detected and replaced with a fallback object
    schema to avoid infinite recursion.  Only local references of the
    form ``#/$defs/<name>`` or ``#/definitions/<name>`` are expanded;
    external ``$ref`` URLs are left unchanged.

    Args:
        schema (`dict`):
            The JSON schema that may contain ``$defs`` and ``$ref``
            references.

    Returns:
        `dict`:
            A flattened JSON schema with all references resolved inline.
    ú$defsÚdefinitionsÚobjÚvisitedr   c                 ó’  •‡— t          | t          ¦  «        rˆˆfd„| D ¦   «         S t          | t          ¦  «        s| S d| v rÕ| d         }t          |t          ¦  «        r¶|                     d¦  «        s|                     d¦  «        rŒ|                     d¦  «        d         }|‰v rt          j        d|¦  «         dd	|› d
�dœS |‰	v rK ‰‰	|         ‰|hz  ¦  «        }|                      ¦   «         D ]\  }}|dk    r ‰|‰|hz  ¦  «        ||<   Œ|S | S i }|                      ¦   «         D ]\  }}|dv rŒ
 ‰|‰¦  «        ||<   Œ|S )Nc                 ó(   •— g | ]} ‰|‰¦  «        ‘ŒS r   r   )Ú.0ÚitemÚ_resolve_refr}   s     €€r   ú
<listcomp>z>_flatten_json_schema.<locals>._resolve_ref.<locals>.<listcomp>;  s%   ø€ Ð@Ð@Ð@°D�L�L  wÑ/Ô/Ð@Ð@Ð@r   z$refz#/$defs/z#/definitions/ú/éÿÿÿÿz3Circular reference detected for '%s' in tool schemaÚobjectz(circular: ú))r   Údescription)rz   r{   )	r8   Úlistr9   r;   Ú
startswithÚsplitr   ÚwarningÚitems)
r|   r}   Úref_pathÚdef_nameÚresolvedÚkeyÚvalueÚresultr‚   Údefss
    `      €€r   r‚   z*_flatten_json_schema.<locals>._resolve_ref9  sÌ  øø€ Ý�c�4Ñ Ô ð 	AØ@Ð@Ð@Ð@Ð@¸CÐ@Ñ@Ô@Ð@Ý˜#�tÑ$Ô$ð 	ØˆJØ�Sˆ=ˆ=Ø˜6”{ˆHÝ˜(¥CÑ(Ô(ð $Ø×#Ò# JÑ/Ô/ð$à×&Ò&Ð'7Ñ8Ô8ð$ð $Ÿ>š>¨#Ñ.Ô.¨rÔ2�Ø˜wÐ&Ð&Ý”Nð!à ñô ð ð !)Ø'@°XÐ'@Ð'@Ð'@ðð ð ð ˜tÐ#Ð#Ø+˜|Ø˜XœØ 8 *Ñ,ñ ô  �Hð '*§i¢i¡k¤kð ð ™
˜˜UØ &š=˜=Ø,8¨LØ %Ø '¨8¨*Ñ 4ñ-ô -˜H S™Møð $�OØˆJØ!#ˆØŸ)š)™+œ+ð 	7ð 	7‰JˆC�ØÐ.Ð.Ð.ØØ&˜, u¨gÑ6Ô6ˆF�3‰KˆKØˆr   )	r8   rh   r9   ÚcopyÚdeepcopyÚupdateÚpopÚ	frozensetr   )r.   Úhas_defsr‚   r”   s     @@r   Ú_flatten_json_schemar›     sC  øø€ õ6 ˜&Ÿ*š* WÑ-Ô-­tÑ4Ô4ð ½
Ø�
Š
�=Ñ!Ô!Ýñ9ô 9€Hð ð ØˆåŒ]˜6Ñ"Ô"€FØ€DÝ�&—*’*˜WÑ%Ô%¥tÑ,Ô,ð )Ø�Š�F—J’J˜wÑ'Ô'Ñ(Ô(Ð(Ý�&—*’*˜]Ñ+Ô+­TÑ2Ô2ð /Ø�Š�F—J’J˜}Ñ-Ô-Ñ.Ô.Ð.àð Øˆå4=±K´Kð (ð (�#ð (­	ð (ÅCð (ð (ð (ð (ð (ð (ð (ðT ˆ<˜ÑÔÐr   c                 ól   — t          t          |                      d¦  «        ¦  «        dz  dz   ¦  «        S )z.Estimate the number of tokens in a given text.rd   é   g      à?)Úintr>   Úencoderw   s    r   Ú_estimate_tokensr    f  s0   € õ �s�4—;’;˜wÑ'Ô'Ñ(Ô(¨1Ñ,¨sÑ2Ñ3Ô3Ð3r   Útokensc                 ó&   — t          | dz  ¦  «        S )z/Estimate the number of bytes with given tokens.r�   )rž   )r¡   s    r   Ú_estimate_bytesr£   l  s   € õ ˆv˜‰z‰?Œ?Ðr   Úerrorc                 óº   — t          | t          ¦  «        r$d                     d„ | j        D ¦   «         ¦  «        S t	          | ¦  «        pt          | ¦  «        j        S )u.  Render an exception as something a person can act on.

    Async transports run inside task groups, so what surfaces is often
    an ``ExceptionGroup`` whose own message is ``"unhandled errors in a
    TaskGroup (1 sub-exception)"`` â€” true, and of no use to anyone. The
    real cause is a leaf, so leaves are what get reported.

    Args:
        error (`BaseException`):
            The exception to describe.

    Returns:
        `str`:
            The leaf causes, joined; the exception type when a leaf
            carries no message of its own.
    z; c              3   ó4   K  — | ]}t          |¦  «        V — Œd S r
   )Ú_describe_exception)r€   Úsubs     r   ú	<genexpr>z&_describe_exception.<locals>.<genexpr>„  s+   è è € ÐNÐN°cÕ,¨SÑ1Ô1ÐNÐNÐNÐNÐNÐNr   )r8   ÚBaseExceptionGroupÚjoinÚ
exceptionsr;   r   r   )r¤   s    r   r§   r§   r  sV   € õ" �%Õ+Ñ,Ô,ð OØ�yŠyÐNÐN¸UÔ=MÐNÑNÔNÑNÔNÐNÝˆu‰:Œ:Ð-�˜e™œÔ-Ð-r   r
   )F)rK   ))Ú__doc__rX   rm   r•   rZ   rR   r6   r)   rU   r   r   Útypingr   r   Ú_loggingr   Ú	exceptionr   r   r;   Ú__annotations__r   r    r"   r$   r&   r,   r9   rF   ÚboolrO   r\   r`   rž   rr   rx   r›   r    r£   ÚBaseExceptionr§   r   r   r   ú<module>r´      sS  ðà 2Ð 2Ð 2Ø €€€Ø €€€Ø €€€Ø Ð Ð Ð Ø €€€Ø €€€Ø 	€	€	€	Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø  Ð  Ð  Ð  Ð  Ð  Ð  Ð  à Ð Ð Ð Ð Ð Ø +Ð +Ð +Ð +Ð +Ð +ð ":Ð!9€ˆX�b˜#�gÔÐ 9Ð 9Ñ 9Ø(JÐ(JÐ �H˜R ˜WÔ%Ð JÐ JÑ Jð˜H R¨ WÔ-ð °$ð ð ð ð ð:! 8¨B°¨GÔ#4ð !¸ð !ð !ð !ð !ð$�cð ð ð ð ð
 ˜Sð  ð  ð  ð  ð5 ð 5¨ð 5ð 5ð 5ð 5ð ðNð NØðNà�4‰KðNð 
ðNð Nð Nð Nðbð  dð °sð ð ð ð ð˜xð ¨Dð ð ð ð ð !Ø
ð!àð!ð ð!ð 	ð	!ð !ð !ð !ð8 ð ð  Ø	ð àð ð 	ð ð  ð  ð  ðF5˜Cð 5 Cð 5ð 5ð 5ð 5ðV  ð V ¨$ð V ð V ð V ð V ðr4˜3ð 4 3ð 4ð 4ð 4ð 4ð˜Cð  Cð ð ð ð ð.˜}ð .°ð .ð .ð .ð .ð .ð .r   