
    PL
j7                        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 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PLATFORM_HINTSSESSION_SEARCH_GUIDANCESKILLS_GUIDANCETOOL_USE_ENFORCEMENT_GUIDANCETOOL_USE_ENFORCEMENT_MODELSc                     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    7/home/kuhnn/.hermes/hermes-agent/agent/system_prompt.py_rar   -   s         agentr   system_messageOptional[str]returnDict[str, str]c                \    t                      g }d} j        s j        s-                                }|r|                    |           d}|s|                    t
                     |                    t                     g }d j        v r|                    t                     d j        v r|                    t                     d j        v r|                    t                     d j        v r|                    t                     |r(|                    d                    |                     d j        v rd	d
lm} |                    |                                j                  }|r|                    |            j        ro j        }d}	|du s+t#          |t$                    r|                                dv rd}	n|du s+t#          |t$                    r|                                dv rd}	nt#          |t(                    r7 j        pd                                t-          fd|D                       }	n; j        pd                                t-          fdt.          D                       }	|	ry|                    t0                      j        pd                                }
d|
v sd|
v r|                    t2                     d|
v sd|
v r|                    t4                     t-           fddD                       }|r:d fd j        D             D             }                     j        |          }nd}|r|                    |            j        dk    rQd j        v r  j                            d          d         n j        }|                    d| d j         d                                           }|r|                    |            j        pd                                                                 }|tB          v r!|                    tB          |                    nR|rP	 d	dl"m#} |$                    |          }|r!|j%        r|                    |j%                   n# tL          $ r Y nw xY wg }||                    |            j        sDtO          j(        d!          pd })                    ||"          }|r|                    |           g } j*        rp j+        r1 j*        ,                    d          }|r|                    |            j-        r1 j*        ,                    d#          }|r|                    |            j.        rB	  j.        /                                }|r|                    |           n# tL          $ r Y nw xY wd	d$l0m1}  |            }d%|2                    d&           } j3        r j4        r|d' j4         z  } j        r|d( j         z  } j        r|d) j         z  }|                    |           d*                    d+ |D                       d*                    d, |D                       d*                    d- |D                       d.S )/u  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.
    FTmemorysession_searchskill_managekanban_show computer_user   )COMPUTER_USE_GUIDANCE>   onyestruealways>   noofffalsenever c              3  n   K   | ]/}t          |t                    |                                v V  0d S N)
isinstancestr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 r0    r4   s     r   r8   z,build_system_prompt_parts.<locals>.<genexpr>   s(      PPq!{*PPPPPPr   geminigemmagptcodexc              3  *   K   | ]}|j         v V  d S r0   )valid_tool_names)r5   namer   s     r   r8   z,build_system_prompt_parts.<locals>.<genexpr>   s+      ttd45#99ttttttr   )skills_list
skill_viewr!   c                    h | ]}||S r:   r:   )r5   toolsets     r   	<setcomp>z,build_system_prompt_parts.<locals>.<setcomp>   s0     
 
 
 

 
 
r   c              3  B   K   | ]}                     |          V  d S r0   )get_toolset_for_tool)r5   	tool_name_rs     r   r8   z,build_system_prompt_parts.<locals>.<genexpr>   sB        7@''	22     r   )available_toolsavailable_toolsets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.)platform_registryNTERMINAL_CWD)cwd	skip_souluser)nowzConversation started: z%A, %B %d, %Y %I:%M %pz
Session ID: z
Model: z
Provider: 

c              3  j   K   | ].}||                                 |                                 V  /d S r0   stripr5   r6   s     r   r8   z,build_system_prompt_parts.<locals>.<genexpr>  <      UUaQU17799U		UUUUUUr   c              3  j   K   | ].}||                                 |                                 V  /d S r0   rX   rZ   s     r   r8   z,build_system_prompt_parts.<locals>.<genexpr>  r[   r   c              3  j   K   | ].}||                                 |                                 V  /d S r0   rX   rZ   s     r   r8   z,build_system_prompt_parts.<locals>.<genexpr>  r[   r   )stablecontextvolatile)5r   load_soul_identityskip_context_filesload_soul_mdappendr   r
   r@   r   r   r   r   joinagent.prompt_builderr%   build_nous_subscription_prompt_tool_use_enforcementr1   r2   r3   listmodelanyr   r   r	   r   build_skills_system_promptprovidersplitbuild_environment_hintsplatformrY   r   gateway.platform_registryrP   getplatform_hint	Exceptionosgetenvbuild_context_files_prompt_memory_store_memory_enabledformat_for_system_prompt_user_profile_enabled_memory_managerbuild_system_prompthermes_timerU   strftimepass_session_id
session_id)r   r   stable_parts_soul_loaded_soul_contenttool_guidancer%   nous_subscription_prompt_enforce_inject_model_lowerhas_skills_toolsavail_toolsetsskills_prompt_model_short
_env_hintsplatform_keyrP   _entrycontext_parts_context_cwdcontext_files_promptvolatile_parts	mem_block
user_block_ext_mem_block_hermes_nowrU   timestamp_linerJ   r7   s   `                            @@r   build_system_prompt_partsr   <   s   * 
B !L
 L  u'?  )) 	 ...L 42333 2333 M5)))_---51114555///_---
 ..._--- 5CHH]33444 ///>>>>>>1222!@@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 $$<(?(?##$CDDDttttFsttttt 
 
   DIDZ  
 
 
 55!2- 6 
 

  +M*** ~""58EK5G5Gu{((--b11U[:, : :%*[: : :	
 	
 	
 ++--J (J'''N(b//117799L~%%N<89999	 	CCCCCC&**<88F :&. :##F$8999 	 	 	D	  "M !^,,,# 	7
 y008D!<<  =  6  6 	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Vcll;S.T.TVVN >!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$   >R 
R('R(0W 
WWr2   c                    t          | |          }d                    d |d         |d         |d         f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   rV   c              3     K   | ]}||V  	d S r0   r:   rZ   s     r   r8   z&build_system_prompt.<locals>.<genexpr>"  s(      ^^Q\]^q^^^^^^r   r^   r_   r`   )r   re   )r   r   partss      r   r}   r}     sL     &eNKKKE;;^^5?E)4DeJFW"X^^^^^^r   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_promptrx   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[]functionrA   descriptionr.   
parametersN)rA   r   r   requiredF)ensure_ascii)toolsrr   rd   jsondumps)r   formatted_toolstoolfuncformatted_tools        r   format_tools_for_system_messager   0  s     ; t O / /JL88M266((<44	
 
 	~....:oE::::r   )r   r}   r   r   r0   )r   r   r   r   r   r   )r   r   r   r   r   r2   )r   r   r   r   )r   r   r   r2   )__doc__
__future__r   r   ru   typingr   r   r   r   rf   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r}   r   r   __all__r:   r   r   <module>r      sd   . # " " " " "  				 , , , , , , , , , , , ,                           S S S S Sl_ _ _ _ _&- - - -; ; ; ;0  r   