
    *"hjxG                       d Z ddlmZ ddlZddlZddlZddlmZ ddlm	Z	 ddl
mZmZ  ej                  e      Zdad	Zd	Zd	Zd	Zd
ZdZddZddZddZddZddZ	 	 	 	 	 	 	 	 	 	 ddZdZdZdZddZ ddZ!d dZ"d!dZ#	 	 	 	 	 	 d"dZ$y)#a  
Session Summarization: for each session, build a lossless structured
trajectory (programmatic) and a trajectory-aware analytical summary (LLM).

Attaches to each session dict:
- ``_trajectory``: structured text preserving the exact step-by-step path
- ``_summary``: LLM-generated analysis focusing on causal chains and insights
- ``_skills_referenced``, ``_avg_prm``, ``_has_tool_errors``: metadata
    )annotationsN)Any   )AsyncLLMClient)compact_tool_callscompact_tool_observations i  i,     c                    t        | xs d      j                         j                  dd      }t        |      |k  r|S |d | dz   S )Nr	   
 u   …)strstripreplacelen)textlimitss      </root/.hermes/SkillClaw/evolve_server/pipeline/summarizer.py_clipr   %   sE    DJB''c2AA%16QvY%66    c           	     p   | j                  d      xs g }| j                  d      xs g }| j                  d      xs g }| j                  d      xs g }i }|D ]-  }t        |t              s|j                  d      s&|||d   <   / |D ]:  }t        |t              s|j                  d      s&|j                  |d   |       < i }|D ]r  }	t        |	t              st	        |	j                  d      xs d      }
t        |	j                  dd      t              }|j                  |
g       j                  |       t g }|d	t         D ]  }t        |t              st        |j                  d
      t              r|j                  d
      ni }t	        |j                  d      xs d      }t        |j                  dd      t              }t	        |j                  d      xs d      }d}|j                  |      }|r|j                  d      rB|j                  dd      }t        |j                  dd      t              }|rd| d| nd| }nXt        |j                  dd      t              }t        |j                  dd      d      }|rd| }|r|d| z  }n
|rd| }nd}|s||v r||   }d|d    }|j                  d| d| d|         g }|d	t         D ch c]8  }t        |t              s|j                  d
      xs i j                  dd      : }}|j                         D ](  \  }
}|
|vs|D ]  }	|j                  d|
 d|	         * |j                  |d	d         t        |      t        kD  r%|j                  d!t        |      t        z
   d"       |S c c}w )#z?Render tool calls with their results/errors into compact lines.
tool_callstool_resultstool_observationstool_errorstool_call_id	tool_namer	   contentNfunctionnameunknown	argumentsid	has_error
error_typeu
    → ✗ [z] u	    → ✗ commandP   u    → ✓ cmd= | u	    → ✓ u    → ✓r   z    ()u       ⚠ z:    z	    ... +z more tool calls)get
isinstancedict
setdefaultr   r   _TOOL_ERR_MAXappend_MAX_TOOLS_PER_STEP_TOOL_ARG_MAX_TOOL_RESULT_MAXitemsextendr   )turn	raw_callsraw_resultsraw_observations
raw_errorsresult_by_idroerror_by_tooletnamer   linestcfuncr!   argscall_idoutcomeerr_typeerr_contentcmderrsleftover_errorscalled_namess                            r   _format_tool_callsrO   *   s   &,"I((>*0bKxx 34:-(.BJ$&L 0a155#8./L>*+0  :a155#8##An$5q9: +-M @ak*0b1EAEE)R0-@G$$UB/66w?	@ E,,- 5"d#%/z0BD%Irvvj!r488F#0y1TXXk2.>bffTl(b)W%uu[!55r2#AEE)R$8:JKDLJxj;-@T]^i]jRki 46FGAEE)R0"5 -cU3GS	?2 )'3G(G4=0 &D!$q'+GtD64&'34?5B O=FG[H[=\79`jkmos`t
		!r&&vr2L  %**, @t$ @&&%1#'>?@@ 
LL!$%
9~++yY2E!E FFVWXLs   ,N3'N3c                    | j                  dg       }|syt        d |D              }t        |d   j                  d      xs dt              }|rt	        ||      S t        ||      S )a  Build a structured trajectory preserving the step-by-step path.

    If the session contains aggregated rollouts (turns carry ``_rollout_idx``),
    the trajectory is organised per-rollout with a header showing ORM score
    and success flag.  The user prompt is shown once at the top and omitted
    from subsequent steps to avoid redundancy.

    Each step shows: skills used, tool calls with outcomes, agent response
    snippet, and PRM / ORM score where available.
    turnsz(empty session)c              3  B   K   | ]  }|j                  d       du  yw)_rollout_idxN)r-   ).0ts     r   	<genexpr>z+build_session_trajectory.<locals>.<genexpr>   s     HQquu^,D8Hs   r   prompt_textr	   )r-   anyr   _PROMPT_MAX_build_rollout_trajectory_build_flat_trajectory)sessionrQ   has_rolloutsfirst_prompts       r   build_session_trajectoryr_   r   si     KK$E  H%HHL %(,,}5;kJL(==!%66r   c           
         g }t        | d      D ]&  \  }}|j                  t        ||||dk(               ( dj                  |      S )z.Single-rollout (or non-aggregated) trajectory.   show_promptr   )	enumerater2   _format_stepjoin)rQ   r^   blocksirU   s        r   r[   r[      sM    F%# N1l1aAFLMN99Vr   c           
        i }| D ]5  }|j                  dd      }|j                  |g       j                  |       7 g }|r%|j                  d|        |j                  d       t        |j	                               D ]  }||   }|d   j                  d      }|d   j                  d      }	|d| nd}
|	d	|	 nd}d
| |
g}|r|j                  |       |j                  ddj                  |       d       t        |d      D ]#  \  }}|j                  t        |||d             % |j                  d        dj                  |      S )z=Multi-rollout aggregated trajectory with per-rollout headers.rS   r   zTask: r	   _rollout_score_rollout_successzORM=zORM=n/azsuccess=zRollout u
   ═══ r)   u
    ═══ra   Frb   r   )r-   r0   r2   sortedkeysrf   rd   re   )rQ   r^   rolloutsrU   idxrg   rollout_idxrollout_turnsormsuccessorm_strsuc_strheader_partsstep_is                 r   rZ   rZ      sq    ')H /eeNA&C$++A./ F|n-.bhmmo.  -A""#34"&&'9:"%/D,y*1*=HWI&2";-0':(
5::l#;"<JGH"=!4 	TIFAMM,q&,ERS	Tb  99Vr   c               &   t        | j                  dd      t              }t        | j                  dd      t              }g }| j                  d      xs g D ]c  }t	        |t
              r |j                  dd      j                         nt        |xs d      j                         }|sS|j                  |       e g }	| j                  d      xs g D ]c  }t	        |t
              r |j                  dd      j                         nt        |xs d      j                         }|sS|	j                  |       e | j                  d      xs g D cg c]=  }t        |xs d      j                         s!t        |xs d      j                         ? }
}| j                  d      }|d	| nd}d
| dg}|r|j                  |       |r|j                  d|        |	r|j                  d|	        |
r|j                  d|
        dj                  |      }|g}|r|r|j                  d|        t        |       }|r"|j                  d       |j                  |       |r|j                  d|        dj                  |      S c c}w )z-Format a single step line for the trajectory.rW   r	   response_textread_skills
skill_namemodified_skillsinjected_skills	prm_scorezPRM=z[Step ]zread_skills=zmodified_skills=z	injected=r)   z  User: z  Tools:z	  Agent: r   )r   r-   rY   _RESPONSE_MAXr.   r/   r   r   r2   rf   rO   r7   )r8   step_numr^   rc   promptresponseskillsr   r!   modifiedinjectedprmprm_strrv   headerrC   
tool_liness                    r   re   re      sW    488M2.<FTXXor2MBHFXXm$*  2<Q2Equu\2&,,.3qwTV<K]K]K_MM$  HXX'(.B "2<Q2Equu\2&,,.3qwTV<K]K]K_OOD!" 04xx8I/J/PbjUXYZY`^`UaUgUgUiAG""$jHj
((;
C!oSEl2GXJa()LG$l6(34.xj9:iz23ZZ%FHEvxx()#D)JZ Z y
+,99U9 ks   "J5Ju  You are a concise analyst for an AI coding assistant framework called SkillClaw.

Given a complete agent session, produce a trajectory-aware analytical summary (8-15 sentences) that captures:

1. **Goal**: The overall task the user wanted to accomplish.
2. **Key trajectory**: The step-by-step path the agent took — what it tried, in what order, and why (e.g., "read skill X → attempted approach Y → hit error Z → switched to W").
3. **Skill effectiveness**: For each skill that was read, injected, or modified, did it help or hurt? Was it relevant to the task? Was any guidance missing or wrong?
4. **Critical turning points**: Where things went right or wrong. What caused failures? What enabled successes?
5. **Tool usage patterns**: Which tools were used effectively, which caused errors, and any recurring patterns.
6. **Outcome**: Final result quality and what could have gone better.

Focus on preserving the SEQUENCE of events and CAUSAL RELATIONSHIPS. This summary will be used to decide whether skills need improvement, so be specific about what skill guidance helped, what was missing, and what was misleading.

Output ONLY the plain-text summary — no JSON, no markdown fences.
i  c                   | j                  dg       }|r|d   j                  d      xs ddt         nd}g }t        |      D ]  \  }}|j                  d      xs ddt         }|dk(  r|n||k(  rdn|}||j                  d      xs ddt         |j                  d      d	}|j                  d
      }	|	5|	|d<   |j                  d      }
|
|
|d<   |j                  d      }|||d<   |j                  d      xs g }|rB|D cg c]3  }t	        |t
              r|j                  dd      nt        |xs d      5 c}|d<   |j                  d      xs g }|rB|D cg c]3  }t	        |t
              r|j                  dd      nt        |xs d      5 c}|d<   |j                  d      xs g }|r||d<   t        |j                  d      d      }|r||d<   t        |j                  d      d      }|r||d<   t        |j                  d      d      }|r||d<   |j                  d      xs g }|r||d<   |j                  |        | j                  dd      t        |      |d}| j                  d      }|rf|j                  d      |j                  d      |j                  d       |j                  d!      |j                  d"      |j                  d#      d$|d<   |S c c}w c c}w )%u   Build a compact representation of the session for the LLM.

    Deduplicates repeating user prompts — only the first occurrence is
    included; subsequent turns with the same prompt get ``prompt: "(same)"``.
    rQ   r   rW   r	   Nz(same)ry   r~   )r   r   r~   rS   rp   rj   rollout_scorerk   rollout_successrz   r{   r|   r}   r      )	max_itemsr   r      r   
session_id)r   total_interactionsinteractions	aggregaterollout_countscores
mean_scoresuccess_count
fail_count	stability)r   r   r   r   r   r   )r-   _SUMMARY_PROMPT_MAX_CHARSrd   _SUMMARY_RESPONSE_MAX_CHARSr.   r/   r   r   r   r2   r   )r\   rQ   r^   r   ro   rU   
raw_promptr   interactionrirsrsurz   r   r|   r   rD   trtotepayloadaggs                         r   _build_session_payloadr     s    KK$EV[E!HLL/527Q8QRacL)+LE" /)QeeM*0b2L3LM
"ax*:ThZd  /527S8ST{+'
 UU>">)+K&'(B~/1O,%%*+C14-.eeM*0bZe*UV:a+>lB'CRLP*K& %% 128bZi.UV:a+>lB'CRLP.K)* 55*+1r-5K)*l 3qA(*K%&quu^'<J*,K'&quu-@'AQO/1K+,UU=!'R)+K&K(_/)d kk,3!%j$G
 ++k
"C
 WW_5ggh''',/ WW_5'',/- 
 NQ*
.s   8K.!8K3c                   t               }g }d}| j                  dg       D ]2  }|j                  d      xs g D ]c  }t        |t              r |j                  dd      j	                         nt        |xs d      j	                         }|sS|j                  |       e |j                  d      xs g D ]c  }t        |t              r |j                  dd      j	                         nt        |xs d      j	                         }|sS|j                  |       e |j                  d      }||j                  |       |j                  d	      s1d
}5 || d<   || d<   |r!t        t        |      t        |      z  d      nd| d<   || d<   y)a  Extract skill references and compute aggregate metrics for a session.

    Attaches the following keys directly to the session dict:
    - ``_skills_referenced``: set of skill names explicitly read or modified
      by any interaction. Prompt-time injection alone is not treated as
      evidence that the session actually used that skill.
    - ``_prm_scores``: list of all non-None PRM scores
    - ``_avg_prm``: mean PRM (or None if no scores)
    - ``_has_tool_errors``: True if any interaction had tool errors
    FrQ   rz   r{   r	   r|   r~   Nr   T_skills_referenced_prm_scoresr,   _avg_prm_has_tool_errors)setr-   r.   r/   r   r   addr2   roundsumr   )r\   r   
prm_scoreshas_tool_errorsr8   itemr!   r   s           r   _extract_session_metadatar   ]  sw    uF JOGR( #HH]+1r 	!D9CD$9O488L"-335UXY]YcacUdUjUjUlD

4 	! HH./52 	!D9CD$9O488L"-335UXY]YcacUdUjUjUlD

4 	! hh{#?c"88M""O# %+G !'GMIS%J#j/ A1EY]GJ"1Gr   c                  K   t        |      }dt        ddt        j                  |d      dg}	 | j	                  |dd       d	{   S 7 # t
        $ r0}t        j                  d
|j                  d      |       Y d	}~yd	}~ww xY ww)z7Summarize an entire session via LLM (trajectory-aware).system)roler   userF)ensure_asciii g?)
max_tokenstemperatureNz/[Summarizer] LLM call failed for session %s: %sr   r	   )	r   _SUMMARIZE_SESSION_SYSTEMjsondumpschat	Exceptionloggerwarningr-   )llmr\   r   messagesrA   s        r   summarize_sessionr     s     $W-G&?@DJJwU$KLHXXh6sXKKKK =KK%	

 s@   /BA 	A
A BA 	B	&B?BB		Bc                >    t        | xs d      j                         ay)z3Set the debug dump directory used by summarization.r	   N)r   r   _SUMMARIZER_DEBUG_DIR)paths    r   set_summarizer_debug_dirr     s      
O113r   c           	     ^  K   |sg S |D ]  }t        |       t        |      |d<    t        j                  |D cg c]  }t	        | |       c}ddi d{   }g }t        ||      D ]S  \  }}t        |t              r(t        j                  d|j                  d      |       d}||d<   |j                  |       U t        }|r;d	dl}|j                  |      d
z  }	|	j                  dd       |D ]  }|j                  dd      j!                  dd      }
|	|
 dz  j#                  |j                  dd      d       |	|
 dz  j#                  |j                  dd      d       t%        |j                  d      xs g       |j                  d      |j                  d      |j                  d      d}|	|
 dz  j#                  t'        j(                  |dd      d        t        j+                  d|	       t        j+                  dt-        |             |S c c}w 7 ӭw)aN  Preprocess and summarize all sessions in parallel.

    For each session:
    1. Extract metadata (``_skills_referenced``, ``_avg_prm``, etc.)
    2. Build programmatic ``_trajectory`` (lossless)
    3. Generate ``_summary`` via LLM (trajectory-aware analysis)

    Returns the list of summary strings (same order as *sessions*).
    _trajectoryreturn_exceptionsTNz)[Summarizer] exception for session %s: %sr   r	   _summaryr   
summarizer)parentsexist_okr"   /_z_trajectory.txtzutf-8)encodingz_summary.txtr   r   r   r   )r   r   r   r   z
_meta.jsonr   F)indentr   z,[DebugDump] wrote summarizer artifacts to %sz#[Summarizer] summarized %d sessions)r   r_   asynciogatherr   zipr.   BaseExceptionr   r   r-   r2   r   pathlibPathmkdirr   
write_textrl   r   r   infor   )r   sessionsr\   r   	summariesresultsummary	debug_dirr   ddirsidmetas               r   summarize_sessions_parallelr     s@     	 C!'*!9'!BC nn-5	6
C
#	6 I
 F)4 	g}-NN;L)
 G%
g	 &I||I&5

4$
/ 	G++lI6>>sCHCse?++77M2.  8  se<((44J+  5 
 '-W[[9M-N-TRT&U#KK
3$+KK0B$C&{{=9	D se:&&22

4>  3 !	( 	BDI KK5s6{CM_ 
7s   8H-H%
H-H*GH-)r   r   r   intreturnr   )r8   r/   r   	list[str])r\   r/   r   r   )rQ   
list[dict]r^   r   r   r   )
r8   r/   r   r   r^   r   rc   boolr   r   )r\   r/   r   zdict[str, Any])r\   r/   r   None)r   r   r\   r/   r   r   )r   r   r   r   )r   r   r   r   r   r   )%__doc__
__future__r   r   r   loggingtypingr   core.llm_clientr   
core.utilsr   r   	getLogger__name__r   r   rY   r   r4   r5   r1   r3   r   rO   r_   r[   rZ   re   r   r   r   r   r   r   r   r    r   r   <module>r      s    #     , F			8	$    7
EP74@1
11 1
 1 	1p 6 ! " Jd!2R$4D	DD Dr   