
    )jI                        d Z ddlm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 ddl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STEER_CHANNEL_NOTETASK_COMPLETION_GUIDANCETOOL_USE_ENFORCEMENT_GUIDANCETOOL_USE_ENFORCEMENT_MODELS)resolve_context_cwdc                     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    :/home/wildlama/.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                     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)          |	t.                    r7 j        pd                                "t3          "fd|	D                       }
n; j        pd                                "t3          "fdt4          D                       }
|
r}|                    t6                      j        pd                                }d|v sd|v r|                    t8                     d|v sd|v sd|v r|                    t:                     t3           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|                    |           t           d#d          r9	 dd$l"m#}  |            }|r|                    |           n# tH          $ r Y nw xY w	 dd%l%m&}  |            }n# tH          $ r d&}Y nw xY w|d&k    r|                    d'           n|                    d(| d)| d*            j'        pd                                (                                }|tR          v r!|                    tR          |                    nR|rP	 dd+l*m+} |,                    |          }|r!|j-        r|                    |j-                   n# tH          $ r Y nw xY wg }||                    |            j        s:!.                    t_                      |,          }|r|                    |           g } j0        rp j1        r1 j0        2                    d          }|r|                    |            j3        r1 j0        2                    d-          }|r|                    |            j4        rB	  j4        5                                }|r|                    |           n# tH          $ r Y nw xY wdd.l6m7}  |            }d/|8                    d0           }  j9        r j:        r| d1 j:         z  }  j        r| d2 j         z  }  j        r| d3 j         z  } |                    |            d4                    d5 |D                       d4                    d6 |D                       d4                    d7 |D                       d8S )9u  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_task_completion_guidancememorysession_searchskill_manage_kanban_worker_guidanceN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 r5    r9   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 r5   )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_viewr%   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 r5   )get_toolset_for_tool)r:   	tool_name_rs     r   r=   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._environment_probe)get_environment_probe_line)_resolve_active_profile_namedefaulta6  Active Hermes profile: default. Other profiles (if any) live under ~/.hermes/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: z3. This session reads and writes ~/.hermes/profiles/u  /. The default profile's data lives at ~/.hermes/skills/, ~/.hermes/plugins/, ~/.hermes/cron/, ~/.hermes/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)cwd	skip_souluser)nowzConversation started: z%A, %B %d, %Yz
Session ID: z
Model: z
Provider: 

c              3  j   K   | ].}||                                 |                                 V  /d S r5   strip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 r5   ra   rc   s     r   r=   z,build_system_prompt_parts.<locals>.<genexpr>\  rd   r   c              3  j   K   | ].}||                                 |                                 V  /d S r5   ra   rc   s     r   r=   z,build_system_prompt_parts.<locals>.<genexpr>]  rd   r   )stablecontextvolatile);r   load_soul_identityskip_context_filesload_soul_mdappendr   r
   getattrrF   r   r   r   r   r   joinr   agent.prompt_builderr*   build_nous_subscription_prompt_tool_use_enforcementr6   r7   r8   listmodelanyr   r   r	   r   build_skills_system_promptprovidersplitbuild_environment_hintstools.env_proberW   	Exceptionagent.file_safetyrX   platformrb   r   gateway.platform_registryrZ   getplatform_hintbuild_context_files_promptr   _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   stable_parts_soul_loaded_soul_contenttool_guidance_kanban_guidancer*   nous_subscription_prompt_enforce_inject_model_lowerhas_skills_toolsavail_toolsetsskills_prompt_model_short
_env_hintsrW   _probe_linerX   active_profileplatform_keyrZ   _entrycontext_partscontext_files_promptvolatile_parts	mem_block
user_block_ext_mem_block_hermes_nowr^   timestamp_linerP   r<   s#   `                                @@r   build_system_prompt_partsr   >   s	   * 
B !L
 L  u'?  )) 	 ...L 42333 2333 u1488 6U=S 64555 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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 $$<(?(?6\CYCY##$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''' 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 # # #"#""	
 	
 	
 	
 	)n ) )-;) ) )
	
 
	
 
	
 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
  "<<#%%  =  ?  ? 	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  sH   'R> >
S
SS   S/.S/>W 
WW.0[ 
[,+[,r7   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   r_   c              3     K   | ]}||V  	d S r5   r?   rc   s     r   r=   z&build_system_prompt.<locals>.<genexpr>q  s(      ^^Q\]^q^^^^^^r   rg   rh   ri   )r   ro   )r   r   partss      r   r   r   a  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_promptr   load_from_disk)r   s    r   invalidate_system_promptr   t  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[]functionrG   descriptionr3   
parametersN)rG   r   r   requiredF)ensure_ascii)toolsr   rm   jsondumps)r   formatted_toolstoolfuncformatted_tools        r   format_tools_for_system_messager     s     ; t O / /JL88M266((<44	
 
 	~....:oE::::r   )r   r   r   r   r5   )r   r   r   r   r   r    )r   r   r   r   r   r7   )r   r   r   r   )r   r   r   r7   )__doc__
__future__r   r   typingr   r   r   r   rp   r   r	   r
   r   r   r   r   r   r   r   r   r   r   agent.runtime_cwdr   r   r   r   r   r   __all__r?   r   r   <module>r      s   . # " " " " "  , , , , , , , , , , , ,                              2 1 1 1 1 1  ` ` ` ` `F	_ _ _ _ _&- - - -; ; ; ;0  r   