
    ީ^jlj                        d Z ddlmZ ddlZddlZddlmZmZmZm	Z	 ddl
mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZ ddlm Z  d	 Z!ddZ"dZ#ddZ$dd dZ%dd!dZ&d"dZ'd#dZ(g dZ)dS )$u@  System-prompt assembly for :class:`AIAgent`.

The agent's system prompt is built once per session and reused across all
turns — only context compression triggers a rebuild.  This keeps the
upstream prefix cache warm.  See ``hermes-agent-dev``'s
``references/system-prompt-invariant.md`` for the invariants and
``references/self-improvement-loop.md`` for how the background-review
fork inherits the cached prompt verbatim.

Three tiers are joined with ``\n\n``:

* ``stable``   — identity (SOUL.md or DEFAULT_AGENT_IDENTITY), tool
  guidance, computer-use guidance, nous subscription block, tool-use
  enforcement guidance + per-model operational guidance, skills prompt,
  alibaba model-name workaround, environment hints, platform hints.
* ``context``  — caller-supplied ``system_message`` plus context files
  (AGENTS.md / .cursorrules / etc.) discovered under ``TERMINAL_CWD``.
* ``volatile`` — memory snapshot, USER.md profile, external memory
  provider block, timestamp/session/model/provider line.

Pure helpers that read the agent's state.  AIAgent keeps thin forwarders.
    )annotationsN)AnyDictListOptional)DEFAULT_AGENT_IDENTITY!GOOGLE_MODEL_OPERATIONAL_GUIDANCEHERMES_AGENT_HELP_GUIDANCEKANBAN_GUIDANCEMEMORY_GUIDANCEOPENAI_MODEL_EXECUTION_GUIDANCEPARALLEL_TOOL_CALL_GUIDANCEPLATFORM_HINTSSESSION_SEARCH_GUIDANCESKILLS_GUIDANCESTEER_CHANNEL_NOTETASK_COMPLETION_GUIDANCETELEGRAM_RICH_MESSAGES_HINTTOOL_USE_ENFORCEMENT_GUIDANCETOOL_USE_ENFORCEMENT_MODELSdrain_truncation_warnings)resolve_context_cwd)get_hermes_home)is_truthy_valuec                     ddl } | S )a  Lazy reference to the ``run_agent`` module.

    Helpers like ``load_soul_md``, ``build_environment_hints``,
    ``build_context_files_prompt``, ``build_nous_subscription_prompt``,
    ``build_skills_system_prompt`` and ``get_toolset_for_tool`` are
    imported into ``run_agent``'s namespace.  Many tests
    ``patch("run_agent.load_soul_md", ...)``; if we imported them
    directly here those patches would not reach us.  Looking them up
    through ``run_agent`` on every call preserves the patch contract.
    r   N	run_agentr   s    5/home/ice/.hermes/hermes-agent/agent/system_prompt.py_rar   5   s         agentr   platform_keystrdefault_hintreturnc                   |s|S t          | dd          }t          |t                    r|s|S |                    |          }||S t          |t                    r1|                                }|r| d|                                 n|S t          |t                    s|S |                    d          }t          |t                    r)|                                r|                                }n|}|                    d          }t          |t                    r?|                                r+| d|                                                                 S |S )u  Apply a per-platform prompt-hint override to the default hint.

    Reads ``agent._platform_hint_overrides`` (populated from
    ``config.yaml`` ``platform_hints`` by ``agent_init``) and resolves the
    effective hint for *platform_key*:

      * ``replace`` — substitute the default hint entirely.
      * ``append``  — keep the default and append the extra text.
      * a bare string value — treated as ``append`` (convenience shorthand).

    Precedence: ``replace`` wins over ``append`` if both are present.
    Override text is added on top of (not instead of) the SOUL/context/
    memory tiers — it only affects the platform-hint segment, so other
    platforms are unaffected and general system instructions still apply.

    Defensive: any malformed entry falls back to the unmodified default so
    a bad config value can never break prompt assembly or leak across
    platforms.
    _platform_hint_overridesN

replaceappend)getattr
isinstancedictgetr#   strip)	r!   r"   r$   	overridesspecextrareplace_textbaseappend_texts	            r   _resolve_platform_hintr6   D   sx   (  94@@Ii&& i ==&&D| $ O

7<N,++E++11333,NdD!! 88I&&L,$$ ););)=)= !!##((8$$K+s## :(9(9(;(; :11K--//1177999Kr    u    You're in its embedded terminal pane, beside the GUI chat — the user can select your output (Option-drag on macOS, Shift-drag elsewhere) and press Cmd/Ctrl+L to send it to the chat composer.hintc                z    | s| S t           | v r| S t          t          j        d                    s| S | t           z   S )u  Append the desktop-embedded-terminal-pane clarifier to a tui hint.

    Triggered by ``HERMES_DESKTOP_TERMINAL=1`` (set by ``main.cjs`` only on the
    shell env of the desktop's embedded TUI PTY — never on the chat backend).
    This is a runtime-surface qualifier, not a config override, so it lives at
    the resolution site rather than inside ``_resolve_platform_hint`` (which
    is purely the config-platform_hints override applier). Byte-stable for the
    cache: called once per session build, deterministically from env state.

    Idempotent and empty-safe: re-applying on an already-augmented hint is a
    no-op, and an empty input returns empty (we never synthesize the
    clarifier without its tui framing).
    HERMES_DESKTOP_TERMINAL)_TUI_EMBEDDED_PANE_CLARIFIERr   osgetenv)r7   s    r   _tui_embedded_pane_clarifierr=   |   sM      #t++29%>??@@ ...r    system_messageOptional[str]Dict[str, str]c                D   ,- t                      ,d}t           dd          }|.t          |dd          }t          |t                    r|dk    r|}g }d} j        s j        s.,                    |          }|r|                    |           d}|s|                    t                     |                    t                     t           dd          r! j
        r|                    t                     t           dd          r! j
        r|                    t                     g }d	 j
        v r|                    t                     d
 j
        v r|                    t                     d j
        v r|                    t                     t           dd          }	|	r|                    |	           n%|	#d j
        v r|                    t                      |r(|                    d                    |                      j
        r|                    t$                     d j
        v r#ddlm}
 |                     |
                       ,                     j
                  }|r|                    |            j
        rs j        }d}|du s+t          |t.                    r|                                dv rd}n|du s+t          |t.                    r|                                dv rd}nt          |t2                    r7 j        pd                                -t7          -fd|D                       }n; j        pd                                -t7          -fdt8          D                       }|r}|                    t:                      j        pd                                }d|v sd|v r|                    t<                     d|v sd|v sd|v r|                    t>                     t7           fddD                       }|rd ,fd j
        D             D             }tA                      }	 ddl!m"}  | j#        tI                                 }n# tJ          $ r tA                      }Y nw xY w,&                     j
        ||pd!          }nd}|r|                    |            j'        d"k    rQd# j        v r  j        (                    d#          d$         n j        }|                    d%| d& j         d'           ,)                                }|r|                    |            j
        rO	 dd(l!m*} |+                     | j#        tI                       j        )                     n# tJ          $ r Y nw xY wt           d*d          r9	 dd+l,m-}  |            }|r|                    |           n# tJ          $ r Y nw xY w	 dd,l.m/}  |            }n# tJ          $ r d-}Y nw xY w|d-k    r5|                    d.t/          ta                                z   d/z              ng|                    d0| d1ta                       d2| d3ta                       d4ta                       d5ta                       d6ta                       d7            j#        pd                                1                                }d}|td          v rtd          |         }n?|r=	 dd8l3m4} |5                    |          }|r|j6        r|j6        }n# tJ          $ r Y nw xY w|d9k    r|r	 dd:l7m8}  |            } | 5                    d;          pi 5                    d9          pi 5                    d<          pi }!|!5                    d=          r|9                                dz   tt          z   }n# tJ          $ r Y nw xY wtw           ||          }"|d>k    r|"rty          |"          }"|"r|                    |"           g }#||#                    |            j        sC,=                    tI                      || j#        d?v @          }$|$r|#                    |$           g }% j>        rp j?        r1 j>        @                    d	          }&|&r|%                    |&            jA        r1 j>        @                    dA          }'|'r|%                    |'            jB        rB	  jB        C                                }(|(r|%                    |(           n# tJ          $ r Y nw xY wddBlDmE})  |)            }*dC|*F                    dD           }+ jG        r jH        r|+dE jH         z  }+ j        r|+dF j         z  }+ j'        r|+dG j'         z  }+|%                    |+           dH                    dI |D                       dH                    dJ |#D                       dH                    dK |%D                       dLS )Mu  Assemble the system prompt as three ordered parts.

    Returns a dict with three keys:
      * ``stable``   — identity, tool guidance, skills prompt,
        environment hints, platform hints, model-family operational
        guidance.
      * ``context``  — context files (AGENTS.md, .cursorrules, etc.)
        and caller-supplied system_message.
      * ``volatile`` — memory snapshot, user profile, external
        memory provider block, timestamp line.

    Joined into a single string by :func:`build_system_prompt` and
    cached on ``agent._cached_system_prompt`` for the lifetime of the
    AIAgent.  Hermes never re-renders parts of this string mid-
    session — that's the only way to keep upstream prompt caches
    warm across turns.
    Ncontext_compressorcontext_lengthr   FT_task_completion_guidance_parallel_tool_call_guidancememorysession_searchskill_manage_kanban_worker_guidancekanban_show computer_use)computer_use_guidance>   onyestruealways>   noofffalsenever c              3  n   K   | ]/}t          |t                    |                                v V  0d S N)r,   r#   lower.0pmodel_lowers     r   	<genexpr>z,build_system_prompt_parts.<locals>.<genexpr>  sA      [[q
STVYHZHZ[!'')){2[[[[[[r    c              3      K   | ]}|v V  	d S rX    rZ   s     r   r^   z,build_system_prompt_parts.<locals>.<genexpr>  s(      PPq!{*PPPPPPr    geminigemmagptcodexgrokc              3  *   K   | ]}|j         v V  d S rX   )valid_tool_names)r[   namer!   s     r   r^   z,build_system_prompt_parts.<locals>.<genexpr>&  s+      ttd45#99ttttttr    )skills_list
skill_viewrH   c                    h | ]}||S r`   r`   )r[   toolsets     r   	<setcomp>z,build_system_prompt_parts.<locals>.<setcomp>(  s0     
 
 
 

 
 
r    c              3  B   K   | ]}                     |          V  d S rX   )get_toolset_for_tool)r[   	tool_name_rs     r   r^   z,build_system_prompt_parts.<locals>.<genexpr>*  sB        7@''	22     r    )coding_compact_skill_categories)platformcwd)available_toolsavailable_toolsetscompact_categoriesalibaba/z#You are powered by the model named z. The exact model ID is zt. When asked what model you are, always answer based on this information, not on any model name returned by the API.)coding_system_blocks)rs   rt   model_environment_probe)get_environment_probe_line)_resolve_active_profile_namedefaultzCActive Hermes profile: default. Other profiles (if any) live under z/profiles/<name>/. Each profile has its own skills/, plugins/, cron/, and memories/ that affect a different session than this one. Do not modify another profile's skills/plugins/cron/memories unless the user explicitly directs you to.zActive Hermes profile: z . This session reads and writes z
/profiles/z'/. The default profile's data lives at z
/skills/, z/plugins/, z/cron/, u/  /memories/ — those belong to a different session run from a different shell. Do NOT modify another profile's skills/plugins/cron/memories unless the user explicitly directs you to. The cross-profile write guard will refuse such writes by default; pass cross_profile=True only after explicit direction.)platform_registrytelegram)load_config_readonly	platformsr2   rich_messagestui)clir   )rt   	skip_soulrC   allow_install_tree_fallbackuser)nowzConversation started: z%A, %B %d, %Yz
Session ID: z
Model: z
Provider: r(   c              3  j   K   | ].}||                                 |                                 V  /d S rX   r/   r[   r\   s     r   r^   z,build_system_prompt_parts.<locals>.<genexpr>	  <      UUaQU17799U		UUUUUUr    c              3  j   K   | ].}||                                 |                                 V  /d S rX   r   r   s     r   r^   z,build_system_prompt_parts.<locals>.<genexpr>
  r   r    c              3  j   K   | ].}||                                 |                                 V  /d S rX   r   r   s     r   r^   z,build_system_prompt_parts.<locals>.<genexpr>  r   r    )stablecontextvolatile)Ir   r+   r,   intload_soul_identityskip_context_filesload_soul_mdr*   r   r
   rg   r   r   r   r   r   r   joinr   agent.prompt_builderrM   build_nous_subscription_prompt_tool_use_enforcementr#   rY   listr|   anyr   r   r	   r   	frozensetagent.coding_contextrr   rs   r   	Exceptionbuild_skills_system_promptprovidersplitbuild_environment_hintsr{   extendtools.env_prober~   agent.file_safetyr   r   r/   r   gateway.platform_registryr   r.   platform_hinthermes_cli.configr   rstripr   r6   r=   build_context_files_prompt_memory_store_memory_enabledformat_for_system_prompt_user_profile_enabled_memory_managerbuild_system_prompthermes_timer   strftimepass_session_id
session_id).r!   r>   _ctx_len_cc_cc_lenstable_parts_soul_loaded_soul_contenttool_guidance_kanban_guidancerM   nous_subscription_prompt_enforce_inject_model_lowerhas_skills_toolsavail_toolsets_compact_catsrr   skills_prompt_model_short
_env_hintsr{   r~   _probe_liner   active_profiler"   _default_hintr   _entryr   _cfg	_tg_extra_effective_hintcontext_partscontext_files_promptvolatile_parts	mem_block
user_block_ext_mem_block_hermes_nowr   timestamp_linerq   r]   s.   `                                           @@r   build_system_prompt_partsr      s   * 
B #H
%-t
4
4C
#/66gs## 	!H !L
 L  u'?  11 	 ...L 42333 2333 u1488 6U=S 64555 u4d;; 9@V 97888 M5)))_---51114555///_---
 u&?FF .-....		!mu7M&M&M_--- 5CHH]33444  0./// ///>>>>>>1133444!@@AWXX 64555  E.t
8S 9 9hnn>N>NRq>q>qGG:h#<#<AQAQUtAtAtGG$'' 	Q ;,"3355K[[[[H[[[[[GG !;,"3355KPPPP4OPPPPPG 	E =>>>!K-24466L <''7l+B+B##$EFFF $$<(?(?6\CYCY##$CDDDttttFsttttt 
 
   DIDZ  
 
 
 "	(LLLLLL;;-@-B-B  MM  	( 	( 	(%KKMMM	(55!2-,4 6 
 
  +M*** ~""58EK5G5Gu{((--b11U[:, : :%*[: : :	
 	
 	
 ++--J (J'''  	AAAAAA$$"^+--+       	 	 	D	 u*D11 	BBBBBB4466K 1##K000 	 	 	D	#BBBBBB5577 # # #"#""?,,--.1	
 	
 	
 	
 	)n ) ))++) )7E) )'6'8'8) )DSDUDU) )   ) ) +:*;*;) ) )
	
 
	
 
	
 N(b//117799L M~%%&|4	 	CCCCCC&**<88F 5&. 5 & 4 	 	 	D	 z!!m!	>>>>>>''))D((;//52:::FFL"QQRYZZ`^`I}}_-- [ - 4 4 6 6 <?Z Z 	 	 	D	 -UL-PPOu6GG -O,,,  "M !^,,,# 7  "<<#%%#(-.(H  =  J  J   	7  !5666 !#N 	2  	1+DDXNNI 1%%i000& 	2,EEfMMJ 2%%j111  	"2FFHHN 6%%n555 	 	 	D	 /.....
+--C Ncll?.K.KMMN >!1 >=5+;==={ 43ek333~ :9999.))) KKUU<UUUUUKKUU=UUUUUKKUU>UUUUU  s   $Q9 9RR=V 
V*)V*?'W' '
W43W48X	 	XX+\2 2
\?>\?B_ 
__0d5 5
eec                    t          | |          }d                    d |d         |d         |d         fD                       }t                      D ]}|                     |           |S )u  Assemble the full system prompt from all layers.

    Called once per session (cached on ``agent._cached_system_prompt``) and
    only rebuilt after context compression events. This ensures the system
    prompt is stable across all turns in a session, maximizing prefix cache
    hits.

    Layers are ordered cache-friendly: stable identity/guidance first,
    then session-stable context files, then per-call volatile content
    (memory, USER profile, timestamp).  The whole string is treated as
    one cached block — Hermes never rebuilds or reinjects parts of it
    mid-session, which is the only way to keep upstream prompt caches
    warm across turns.
    )r>   r(   c              3     K   | ]}||V  	d S rX   r`   r   s     r   r^   z&build_system_prompt.<locals>.<genexpr>  s(      ``q^_```````r    r   r   r   )r   r   r   _emit_status)r!   r>   partsjoinedwarnings        r   r   r     s~     &eNKKKE[[``U8_eI6FjHY$Z`````F -.. $ $7####Mr    Nonec                X    d| _         | j        r| j                                         dS dS )zInvalidate the cached system prompt, forcing a rebuild on the next turn.

    Called after context compression events. Also reloads memory from disk
    so the rebuilt prompt captures any writes from this session.
    N)_cached_system_promptr   load_from_disk)r!   s    r   invalidate_system_promptr   )  s<     #'E -**,,,,,- -r    c                    | j         sdS g }| j         D ]T}|d         }|d         |                    dd          |                    di           dd}|                    |           Ut          j        |d	
          S )zFormat tool definitions for the system message in the trajectory format.

    Returns:
        str: JSON string representation of tool definitions
    z[]functionrh   descriptionrV   
parametersN)rh   r   r   requiredF)ensure_ascii)toolsr.   r*   jsondumps)r!   formatted_toolstoolfuncformatted_tools        r   format_tools_for_system_messager   4  s     ; t O / /JL88M266((<44	
 
 	~....:oE::::r    )r   r   r   r   )r!   r   r"   r#   r$   r#   r%   r#   )r7   r#   r%   r#   rX   )r!   r   r>   r?   r%   r@   )r!   r   r>   r?   r%   r#   )r!   r   r%   r   )r!   r   r%   r#   )*__doc__
__future__r   r   r;   typingr   r   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   agent.runtime_cwdr   hermes_constantsr   utilsr   r   r6   r:   r=   r   r   r   r   __all__r`   r    r   <module>r      s   . # " " " " "  				 , , , , , , , , , , , ,                                   $ 2 1 1 1 1 1 , , , , , , ! ! ! ! ! !  . . . .d2 / / / /.y y y y yx    4- - - -; ; ; ;0  r    