
    i	d                       U d Z ddlmZ ddlZddlZddlZddlmZmZ ddl	m
Z
 ddlmZ ddlmZmZ erddlmZ  ej        e          Z e
j                    d	z  d
z  ZdZd<dZd=dZddiZh dZd>dZd?dZd@dZdAdZdZ dBd Z!dCd$Z"d%d&hZ#d%d&d&d'Z$d>d(Z%d)d)d)d)d*d)d+d+d)d*d,Z&dDd1Z'e G d2 d3                      Z(da)d4e*d5<   dEdFd9Z+dGd;Z,dS )Ha  Honcho client initialization and configuration.

Resolution order for config file:
  1. $HERMES_HOME/honcho.json  (instance-local, enables isolated Hermes instances)
  2. ~/.honcho/config.json     (global, shared across all Honcho-enabled apps)
  3. Environment variables     (HONCHO_API_KEY, HONCHO_ENVIRONMENT)

Resolution order for host-specific settings:
  1. Explicit host block fields (always win)
  2. Flat/global fields from config root
  3. Defaults (host name as workspace/peer)
    )annotationsN)	dataclassfield)Path)get_hermes_home)AnyTYPE_CHECKINGHonchoz.honchozconfig.jsonhermesreturnstrc                     t           j                            dd                                          } | r| S 	 ddlm}  |            }|r|dvrt           d| S n# t          $ r Y nw xY wt          S )a	  Derive the Honcho host key from the active Hermes profile.

    Resolution order:
      1. HERMES_HONCHO_HOST env var (explicit override)
      2. Active profile name via profiles system -> ``hermes.<profile>``
      3. Fallback: ``"hermes"`` (default profile)
    HERMES_HONCHO_HOST r   )get_active_profile_name)defaultcustom.)osenvirongetstriphermes_cli.profilesr   HOST	Exception)explicitr   profiles      D/home/agentuser/.hermes/hermes-agent/plugins/memory/honcho/client.pyresolve_active_hostr    "   s     z~~2B77==??H ??????))++ 	'w&;;;&&W&&&   Ks   !A 
A('A(r   c                     t                      dz  } |                                 r| S t          j                    dz  dz  }|| k    r|                                r|S t          S )uo  Return the active Honcho config path.

    Resolution order:
      1. $HERMES_HOME/honcho.json      (profile-local, if it exists)
      2. ~/.hermes/honcho.json          (default profile — shared host blocks live here)
      3. ~/.honcho/config.json          (global, cross-app interop)

    Returns the global path if none exist (for first-time setup writes).
    zhoncho.jsonz.hermes)r   existsr   homeGLOBAL_CONFIG_PATH)
local_pathdefault_paths     r   resolve_config_pathr'   8   sm     !""]2J  9;;*]:Lz!!l&9&9&;&;!    autohybrid>   toolsr*   contextvalc                R    t                               | |           } | t          v r| ndS )u?   Normalize legacy recall mode values (e.g. 'auto' → 'hybrid').r*   )_RECALL_MODE_ALIASESr   _VALID_RECALL_MODESr-   s    r   _normalize_recall_moder2   R   s,    

"
"3
,
,C,,,33(:r(   r   boolc               J    | t          |           S |t          |          S |S )z@Resolve a bool config field: host wins, then root, then default.)r3   )host_valroot_valr   s      r   _resolve_boolr7   X   s+    H~~H~~Nr(   
int | Nonec                j    | |fD ]-}|)	 t          |          c S # t          t          f$ r Y )w xY w.dS )z@Parse contextTokens: host wins, then root, then None (uncapped).N)int
ValueError	TypeErrorr5   r6   r-   s      r   _parse_context_tokensr>   a   s`    (#  ?3xx	*    
 4s   //r:   c           	         | |fD ]I}|E	 t          dt          t          |          d                    c S # t          t          f$ r Y Ew xY wJdS )zCParse dialecticDepth: host wins, then root, then 1. Clamped to 1-3.N      )maxminr:   r;   r<   r=   s      r   _parse_dialectic_depthrD   l   sw    (#  ?1c#c((A../////	*    
 1s   *7A
A)minimallowmediumhighrB   depthlist[str] | Nonec                    | |fD ]l}|ht          |t                    rSd |d|         D             }t          |          |k     r(|                    d           t          |          |k     (|c S mdS )zParse dialecticDepthLevels: optional array of reasoning levels per pass.

    Returns None when not configured (use proportional defaults).
    When configured, validates each level and truncates/pads to match depth.
    Nc                (    g | ]}|t           v r|nd S )rF   )_VALID_REASONING_LEVELS).0lvls     r   
<listcomp>z1_parse_dialectic_depth_levels.<locals>.<listcomp>   s7        5555  r(   rF   )
isinstancelistlenappend)r5   r6   rI   r-   levelss        r   _parse_dialectic_depth_levelsrV   z   s     (# 	 	?z#t44? vv;  F
 f++%%e$$$ f++%%MMM4r(   valuesr   float | Nonec                     | D ]c}|t          |t                    r|                                }|s1	 t          |          }n# t          t
          f$ r Y Uw xY w|dk    r|c S ddS )z=Return the first non-empty value coerced to a positive float.Nr   )rQ   r   r   floatr<   r;   )rW   valueparseds      r   _resolve_optional_floatr]      s      =eS!! 	KKMME 	5\\FF:& 	 	 	H	A::MMM 4s   AAAunifieddirectional)sharedseparatecrossc                R    t                               | |           } | t          v r| ndS )z"Normalize observation mode values.r_   )_OBSERVATION_MODE_ALIASESr   _VALID_OBSERVATION_MODESr1   s    r   _normalize_observation_moderf      s,    
#
'
'S
1
1C11133}Dr(   Tuser_observe_meuser_observe_othersai_observe_meai_observe_othersF)r_   r^   modeobservation_objdict | Nonedictc                   t                               | t           d                   }|rt          |t                    st          |          S |                    d          pi }|                    d          pi }|                    d|d                   |                    d|d                   |                    d|d                   |                    d|d	                   d
S )aj  Resolve per-peer observation booleans.

    Config forms:
      String shorthand:  ``"observationMode": "directional"``
      Granular object:   ``"observation": {"user": {"observeMe": true, "observeOthers": true},
                                           "ai": {"observeMe": true, "observeOthers": false}}``

    Granular fields override preset defaults.
    r_   userai	observeMerh   observeOthersri   rj   rk   rg   )_OBSERVATION_PRESETSr   rQ   ro   )rl   rm   preset
user_blockai_blocks        r   _resolve_observationry      s     "%%d,@,OPPF *_d"C"C F|| $$V,,2J""4((.BH &>>+v>O7PQQ)~~ovF[?\]]!k6/3JKK%\\/6BU;VWW	  r(   c                  T   e Zd ZU dZeZded<   dZded<   dZded<   d	Z	ded
<   dZ
ded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded<   d Zded!<   dZd"ed#<   d$Zded%<   d&Zded'<   d(Zded)<   dZded*<   d+Zded,<   dZded-<   dZded.<   dZded/<   dZded0<   d1Z ded2<   dZ!ded3<    e"e#4          Z$d5ed6<    e"e#4          Z%d7ed8<   dZ&ded9<   e'	 	 dEdFd;            Z(e'	 	 dGdHd>            Z)e*dId@            Z+	 	 	 	 dJdKdDZ,dS )LHonchoClientConfigz>Configuration for Honcho client, resolved for a specific host.r   hostr   workspace_idN
str | Noneapi_key
productionenvironmentbase_urlrX   timeout	peer_nameai_peerFr3   enabledTsave_messagesasyncz	str | intwrite_frequencyr8   context_tokensrF   dialectic_reasoning_leveldialectic_dynamicX  r:   dialectic_max_charsr@   dialectic_depthrJ   dialectic_depth_levelsa  message_max_chars'  dialectic_max_input_charsr*   recall_modeinit_on_session_startr_   observation_moderh   ri   rj   rk   per-directorysession_strategysession_peer_prefix)default_factoryzdict[str, str]sessionszdict[str, Any]rawexplicitly_configuredr   c                   |pt                      }t          j                            d          }t          j                            dd                                          pd}t          t          j                            d                    } | |||t          j                            dd          |||t          |p|                    S )	z4Create config from environment variables (fallback).HONCHO_API_KEYHONCHO_BASE_URLr   NHONCHO_TIMEOUTHONCHO_ENVIRONMENTr   )r|   r}   r   r   r   r   r   r   )r    r   r   r   r   r]   r3   )clsr}   r|   resolved_hostr   r   r   s          r   from_envzHonchoClientConfig.from_env  s     5 3 5 5*..!122:>>"3R88>>@@HD)"*..9I*J*JKKs%
';\JJ!,H--	
 	
 	
 		
r(   config_pathPath | Nonec                   |pt                      }|pt                      }|                                s1t                              d|           |                     |          S 	 t          j        |                    d                    }nU# t          j	        t          f$ r<}t                              d||           |                     |          cY d}~S d}~ww xY w|                    d          pi                     |i           }t          |          p|                    d          d	u }|                    d
          p|                    d
          p|}	|                    d          p|                    d          p|}
|                    d          p3|                    d          pt          j                            d          }|                    d          p|                    dd          }|                    d          pH|                    d          p3t          j                            dd                                          pd}t#          |                    d          |                    d          t          j                            d                    }|                    d          }|                    d          }||}n||}nt          |p|          }|                    d          p|                    d          pd}	 t%          |          }n&# t&          t(          f$ r t+          |          }Y nw xY w|                    d          }||n|                    dd	          }|                    d          p|                    dd          }|                    d          }||n|                    dd          } | dHi d|d|	d |d|d|d|d!|                    d"          p|                    d"          d#|
d|d$|d%|d&t-          |                    d'          |                    d'                    d(|                    d)          p|                    d)          pd*d+t/          |                    d,          |                    d,          d	-          d.t%          |                    d/          p|                    d/          pd0          d1t1          |                    d2          |                    d2                    d3t3          |                    d4          |                    d4          t1          |                    d2          |                    d2                    5          d6t%          |                    d7          p|                    d7          pd8          d9t%          |                    d:          p|                    d:          pd;          d<t5          |                    d=          p|                    d=          pd>          d?t/          |                    d@          |                    d@          d-          dAt7          |                    dB          p|                    dB          p|rdCndD          t9          t7          |                    dB          p|                    dB          p|rdCndD          |                    dE          p|                    dE                    |||                    dFi           ||dGS )IzCreate config from the resolved Honcho config path.

        Resolution: $HERMES_HOME/honcho.json -> ~/.honcho/config.json -> env vars.
        When host is None, derives it from the active Hermes profile.
        z2No global Honcho config at %s, falling back to env)r|   zutf-8)encodingz*Failed to read %s: %s, falling back to envNhostsr   T	workspaceaiPeerapiKeyr   r   r   baseUrlr   r   r   r   requestTimeoutr   writeFrequencyr   saveMessagessessionStrategyr   sessionPeerPrefixFr|   r}   r   r   peerNamer   r   r   r   contextTokensr   dialecticReasoningLevelrF   r   dialecticDynamic)r   r   dialecticMaxCharsr   r   dialecticDepthr   dialecticDepthLevels)rI   r   messageMaxCharsr   r   dialecticMaxInputCharsr   r   
recallModer*   r   initOnSessionStartr   observationModer^   r_   observationr   )r   r   r   r   r    )r    r'   r"   loggerdebugr   jsonloads	read_textJSONDecodeErrorOSErrorwarningr   r3   r   r   r   r]   r:   r<   r;   r   r>   r7   rD   rV   r2   rf   ry   )r   r|   r   r   pathr   e
host_block_explicitly_configuredr   r   r   r   r   r   host_enabledroot_enabledr   raw_wfr   	host_saver   r   host_prefixr   s                            r   from_global_configz%HonchoClientConfig.from_global_config5  sx    5 3 5 53133{{}} 	4LLMtTTT<<]<333	4*T^^W^==>>CC$g. 	4 	4 	4NNGqQQQ<<]<33333333	4 ggg&&,"11-DD
 "&j!1!1!OSWWY5G5G45O NN;'' ww{## 	 NN8$$ wwx   	 NN8$$ 0wwx  0z~~.// 	 NN=)) 4ww}l33 	 GGI wwz""z~~/44::<< 	 	 *GGIGG$%%JNN+,,
 
 "~~i00wwy))#"GG%"GG 7.h//G NN+,, ww'(( 	
	*),VOO:& 	* 	* 	*!&kkOOO	* NN>22	%.%:		X\@]@] NN,-- ;ww(/:: 	 !nn%899&2KK,e44 	
 s S
 S
 S
S
"S
 GS
 $	S

 XS
 GS
 !nnZ00GCGGJ4G4GS
 GS
 GS
 (-S
 ,OS
 1//((  S
" 899 77455'S
* ,122*++   +S
4 !$233 77.//! ! !5S
> 3/00())  ?S
F $A566.//,Z^^<L-M-MswwWgOhOhii$ $ $ $GS
P "011 77,--  QS
Z '*788 77344' ' '[S
d /|,, 77<((  eS
n #0344,--# # # #oS
B 9011 L77,--L!7JII]  
 #+NN#455 Pww011P%;N		 
 }--G1G1G MS
\ . 3WWZ,,"8eS
 S
 S
 S
 S	
s0   '(B C"&1CC"C"&L6 6 MMcwdc                    ddl }	 |                    g ddd| d          }|j        dk    r+t          |j                                                  j        S n# t          |j        f$ r Y nw xY wdS )zBReturn the git repo root directory name, or None if not in a repo.r   N)gitz	rev-parsez--show-toplevelT   )capture_outputtextr   r   )	
subprocessrun
returncoder   stdoutr   namer   TimeoutExpired)r   r   roots      r   _git_repo_namez!HonchoClientConfig._git_repo_name  s     		>>777#$C "  D !##DK--//0055 $23 	 	 	D	ts   AA A-,A-session_title
session_idgateway_session_keyc                   ddl }|st          j                    }| j                            |          }|r|S |rH|                    dd|                              d          }|r| j        r| j        r| j         d| S |S |r.|                    dd|                              d          }|r|S | j	        dk    r|r| j        r| j        r| j         d| S |S | j	        dk    rE| 
                    |          pt          |          j        }| j        r| j        r| j         d| S |S | j	        dv r0t          |          j        }| j        r| j        r| j         d| S |S | j        S )u  Resolve Honcho session name.

        Resolution order:
          1. Manual directory override from sessions map
          2. Hermes session title (from /title command)
          3. Gateway session key (stable per-chat identifier from gateway platforms)
          4. per-session strategy — Hermes session_id ({timestamp}_{hex})
          5. per-repo strategy — git repo root directory name
          6. per-directory strategy — directory basename
          7. global strategy — workspace name
        r   Nz[^a-zA-Z0-9_-]+-per-sessionzper-repo)r   r   )rer   getcwdr   r   subr   r   r   r   r   r   r   r}   )	selfr   r   r   r   r   manual	sanitizedbases	            r   resolve_session_namez'HonchoClientConfig.resolve_session_name  s   $ 				 	)++C ""3'' 	M  	!13FFLLSQQI !+ ; ;"n::y:::    	!138KLLRRSVWWI !    M11j1' 8DN 8.77:777  J..&&s++=tCyy~D' 2DN 2.114111K  $DDD99>D' 2DN 2.114111K   r(   )r   N)r}   r   r|   r~   r   r{   )NN)r|   r~   r   r   r   r{   )r   r   r   r~   )NNNN)
r   r~   r   r~   r   r~   r   r~   r   r~   )-__name__
__module____qualname____doc__r   r|   __annotations__r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rh   ri   rj   rk   r   r   r   ro   r   r   r   classmethodr   r   staticmethodr   r   r   r(   r   r{   r{      s        HHD L    G#K####H G     I    GGM ")O((((!%N%%%% &+**** #""""""""" O 043333 #""""%*****
  K #('''' *)))) !O     $$$$$M"""""+++++ %%%%%$uT:::H::::%555C5555 #('''' %
 
 
 
 [
*   #'v
 v
 v
 v
 [v
p    \" $(!%*.C! C! C! C! C! C! C!r(   r{   zHoncho | None_honcho_clientconfigHonchoClientConfig | Noner   c                H   t           t           S | t                                          } | j        s| j        st          d          	 ddlm} n# t          $ r t          d          w xY w| j        }| j	        }|r|	 ddl
m}  |            }|                    di           }t          |t                    rd|s*|                    dd	                                          pd}|6t!          |                    d
          |                    d                    }n# t"          $ r Y nw xY w|r"t$                              d|| j                   n&t$                              d| j        | j                   |od|v pd|v pd|v }|rg| j        pi }|                    d          pi                     | j        i           }	t/          |	                    d                    }
|
r| j        nd}n| j        }| j        || j        d}|r||d<   |||d
<    |di |a t           S )zGet or create the Honcho client singleton.

    When no config is provided, attempts to load ~/.honcho/config.json
    first, falling back to environment variables.
    NzHoncho API key not found. Get your API key at https://app.honcho.dev, then run 'hermes honcho setup' or set HONCHO_API_KEY. For local instances, set HONCHO_BASE_URL instead.r   r
   zThoncho-ai is required for Honcho integration. Install it with: pip install honcho-ai)load_confighonchor   r   r   request_timeoutz8Initializing Honcho client (base_url: %s, workspace: %s)z4Initializing Honcho client (host: %s, workspace: %s)	localhostz	127.0.0.1z::1r   r   local)r}   r   r   r   )r   r{   r   r   r   r;   r   r   ImportErrorr   hermes_cli.configr   r   rQ   ro   r   r]   r   r   infor}   r|   r   r3   r   )r   r   resolved_base_urlresolved_timeoutr   
hermes_cfg
honcho_cfg	_is_local_raw_host_block_host_has_keyeffective_api_keykwargss                r   get_honcho_clientr  G  s    !~#6688> 
&/ 
@
 
 	

!!!!!!! 
 
 
5
 
 	

 ~  0 8	555555$J#"55J*d++ ( W(2z2(F(F(L(L(N(N(VRV%#+'>"y11"'899( ($  	 	 	D	  nNPacicvwwwwJFKY_Ylmmm " (( 	&++	&%% 
  +zRxx((.B33FKDD[__X6677.;HFNN"N +$) F
  /.z#,yV%%f%%Ns   A A)?BD 
D,+D,Nonec                 
    da dS )z7Reset the Honcho client singleton (useful for testing).N)r   r   r(   r   reset_honcho_clientr    s     NNNr(   )r   r   )r   r   )r-   r   r   r   )r   r3   r   r3   )r   r8   )r   r:   )rI   r:   r   rJ   )rW   r   r   rX   )rl   r   rm   rn   r   ro   )N)r   r   r   r   )r   r  )-r   
__future__r   r   r   loggingdataclassesr   r   pathlibr   hermes_constantsr   typingr   r	   r   r   	getLoggerr   r   r#   r$   r   r    r'   r/   r0   r2   r7   r>   rD   rM   rV   r]   re   rd   rf   ru   ry   r{   r   r   r  r  r   r(   r   <module>r     s     # " " " " "  				  ( ( ( ( ( ( ( (       , , , , , , % % % % % % % % 		8	$	$TY[[9,}<    ,   , ) 444 ; ; ; ;          F    &   $ &}5 '0mVcdd E E E E  D 
  T 	 	    > j! j! j! j! j! j! j! j!Z !% $ $ $ $W W W W Wt     r(   