§
    –$j—  ã                  ór   — U d Z ddlmZ ddlmZmZ dZdZdZda	de
d<   dd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS )uç  Configurable tool-output truncation limits.

Ported from anomalyco/opencode PR #23770 (``feat(truncate): allow
configuring tool output truncation limits``).

OpenCode hardcoded ``MAX_LINES = 2000`` and ``MAX_BYTES = 50 * 1024``
as tool-output truncation thresholds. Hermes-agent had the same
hardcoded constants in two places:

* ``tools/terminal_tool.py`` â€” ``MAX_OUTPUT_CHARS = 50000`` (terminal
  stdout/stderr cap)
* ``tools/file_operations.py`` â€” ``MAX_LINES = 2000`` /
  ``MAX_LINE_LENGTH = 2000`` (read_file pagination cap + per-line cap)

This module centralises those values behind a single config section
(``tool_output`` in ``config.yaml``) so power users can tune them
without patching the source. The existing hardcoded numbers remain as
defaults, so behaviour is unchanged when the config key is absent.

Example ``config.yaml``::

    tool_output:
      max_bytes: 100000        # terminal output cap (chars)
      max_lines: 5000          # read_file pagination + truncation cap
      max_line_length: 2000    # per-line length cap before '... [truncated]'

The limits reader is defensive: any error (missing config file, invalid
value type, etc.) falls back to the built-in defaults so tools never
fail because of a malformed config.
é    )Úannotations)ÚAnyÚDictiPÃ  iÐ  Nzdict | NoneÚ_cached_limitsÚvaluer   ÚdefaultÚintÚreturnc                ój   — 	 t          | ¦  «        }n# t          t          f$ r |cY S w xY w|dk    r|S |S )z@Return ``value`` as a positive int, or ``default`` on any issue.r   )r	   Ú	TypeErrorÚ
ValueError)r   r   Úivs      ú7/usr/local/lib/hermes-agent/tools/tool_output_limits.pyÚ_coerce_positive_intr   0   sP   € ðÝ‰ZŒZˆˆøÝ•zÐ"ð ð ð Øˆˆˆðøøøà	ˆQ‚w€wØˆØ€Is   ‚ ’(§(úDict[str, int]c                 óî  — t           t           S 	 ddlm}   | ¦   «         pi }t          |t          ¦  «        r|                     d¦  «        nd}t          |t          ¦  «        si }n# t          $ r i }Y nw xY wt          |                     d¦  «        t          ¦  «        t          |                     d¦  «        t          ¦  «        t          |                     d¦  «        t          ¦  «        dœa t           S )	a¾  Return resolved tool-output limits, reading ``tool_output`` from config.

    Keys: ``max_bytes``, ``max_lines``, ``max_line_length``. Missing or
    invalid entries fall through to the ``DEFAULT_*`` constants. This
    function NEVER raises.

    Result is cached for the process lifetime to avoid repeated disk I/O
    on every tool call. Call ``_reset_tool_output_limits_cache()`` in
    tests that need a fresh read after config changes.
    Nr   )Úload_configÚtool_outputÚ	max_bytesÚ	max_linesÚmax_line_length)r   r   r   )r   Úhermes_cli.configr   Ú
isinstanceÚdictÚgetÚ	Exceptionr   ÚDEFAULT_MAX_BYTESÚDEFAULT_MAX_LINESÚDEFAULT_MAX_LINE_LENGTH)r   ÚcfgÚsections      r   Úget_tool_output_limitsr"   ;   s  € õ Ð!ÝÐðØ1Ð1Ð1Ð1Ð1Ð1Øˆk‰mŒmÐ!˜rˆÝ,6°s½DÑ,AÔ,AÐK#—'’'˜-Ñ(Ô(Ð(ÀtˆÝ˜'¥4Ñ(Ô(ð 	ØˆGøøÝð ð ð Øˆˆˆðøøøõ *¨'¯+ª+°kÑ*BÔ*BÕDUÑVÔVÝ)¨'¯+ª+°kÑ*BÔ*BÕDUÑVÔVÝ/ØKŠKÐ)Ñ*Ô*Õ,Cñ
ô 
ðð €Nõ Ðs   AA& Á&A5Á4A5ÚNonec                 ó
   — da dS )uA   Reset the cached limits â€” for tests or after config hot-reload.N)r   © ó    r   Ú_reset_tool_output_limits_cacher'   \   s   € ð €N€N€Nr&   c                 ó*   — t          ¦   «         d         S )z?Shortcut for terminal-tool callers that only need the byte cap.r   ©r"   r%   r&   r   Úget_max_bytesr*   b   ó   € å!Ñ#Ô# KÔ0Ð0r&   c                 ó*   — t          ¦   «         d         S )z:Shortcut for file-ops callers that only need the line cap.r   r)   r%   r&   r   Úget_max_linesr-   g   r+   r&   c                 ó*   — t          ¦   «         d         S )z>Shortcut for file-ops callers that only need the per-line cap.r   r)   r%   r&   r   Úget_max_line_lengthr/   l   s   € å!Ñ#Ô#Ð$5Ô6Ð6r&   )r   r   r   r	   r
   r	   )r
   r   )r
   r#   )r
   r	   )Ú__doc__Ú
__future__r   Útypingr   r   r   r   r   r   Ú__annotations__r   r"   r'   r*   r-   r/   r%   r&   r   ú<module>r4      sê   ððð ð ð> #Ð "Ð "Ð "Ð "Ð "à Ð Ð Ð Ð Ð Ð Ð ð
 Ð ØÐ ØÐ ð #€Ð "Ð "Ð "Ñ "ðð ð ð ðð ð ð ðBð ð ð ð1ð 1ð 1ð 1ð
1ð 1ð 1ð 1ð
7ð 7ð 7ð 7ð 7ð 7r&   