
    MJiD                     h    S r SSKrSSKrSSKrSSKJrJrJrJr  SSK	J	r	  SSK
JrJr   " S S5      rg)u   
Prompt 模板编译器

将模板化的 Prompt 编译为最终的 AI 指导文件。
支持变量插值、条件渲染、循环渲染等功能。
    N)DictAnyListOptional)datetime)CategoryConfigPromptTemplatec            	          \ rS rSrSr/ SQrS-S\4S jjrS-S\S\\\	4   S	\4S
 jjr
 S-S\S\S\\\	4   S	\4S jjrS\S\\\	4   S	\\\	4   4S jrS-S\S\\\	4   S	\\\	4   4S jjrS\S\\\	4   S	\4S jrS\S\\\	4   S	\4S jrS\S\\\	4   S	\4S jrS\S\\\	4   S	\4S jrS\S\\\	4   S	\	4S jrS\S\\\	4   S	\4S jrS\S\\\	4   S	\4S jrS\	S\S	\4S jrS\S	\\   4S  jrS\S	\\   4S! jrS\S	\\   4S" jrS\S	\4S# jrS\S$\S	\4S% jrS\S	\\   4S& jrS\S'\S	\\\\	4      4S( jr S\S	\4S) jr!S-S\S*\S	\4S+ jjr"S,r#g).PromptCompiler   u   Prompt 模板编译器)category
difficultylanguageknowledge_pointssceneextra_requirementswriteup_count	timestampmax_knowledgedepth_range	diff_rateN	base_pathc                     U=(       dA    [         R                  R                  [         R                  R                  [        5      S5      U l        g)uD   
初始化编译器

Args:
    base_path: Prompt 模板基础路径
z../../../ge10N)ospathjoindirname__file__r   )selfr   s     M   /Users/yu22x/Desktop/ddd_副本6/ctf/app/services/category/prompt_compiler.py__init__PromptCompiler.__init__   s,     #^bggll277??83Lo&^    category_id
user_inputreturnc                 z   [         R                  R                  U5      nU(       d  [        SU S35      eU R	                  X25      n[
        R                  R                  USSS9R                  5       nU(       a  UR                  (       a  UR                  nOU R                  U5      nU R                  Xd5      nU$ )u   
编译完整的 Prompt

Args:
    category_id: 方向 ID
    user_input: 用户输入的参数（可选，用于预览）
    
Returns:
    编译后的完整 Prompt 字符串
   方向 '   ' 不存在mainT)r$   template_type	is_active)r   queryget
ValueError_build_contextr	   	filter_byfirstcontent_load_file_template_render_template)r   r$   r%   r   contextmain_templateprompt_contentcompiled_prompts           r    compilePromptCompiler.compile#   s     "''++K8x}K@AA %%h; ',,66#  7 
 %'	 	 ]22*22N "55h?N //Hr#   template_contentc                     [         R                  R                  U5      nU(       d  [        SU S35      eU R	                  XC5      nU R                  X5      $ )u   
从模板内容编译 Prompt（用于预览）

Args:
    template_content: 模板内容
    category_id: 方向 ID
    user_input: 用户输入的参数
    
Returns:
    编译后的 Prompt 字符串
r(   r)   )r   r-   r.   r/   r0   r5   )r   r<   r$   r%   r   r6   s         r    compile_from_template$PromptCompiler.compile_from_templateI   sS     "''++K8x}K@AA%%h;$$%5??r#   category_configc           
         / n/ nU R                  U5      nU R                  U5      nUR                  S/ 5      n[        U5      [        U5      :w  a*  UR	                  S[        U5       S[        U5       S35        UR                  S/ 5       Vs/ s H  oS   PM	     n	nU H_  n
X;  d  M
  XR
                  ;  d  M  U
R                  S5      (       a  M3  U
R                  S5      (       a  MK  UR	                  S	U
 35        Ma     UR                  S
/ 5       Vs/ s H  oS   PM	     nnU R                  U5      nU(       a/  [        U5      [        U5      :w  a  UR	                  SU SU 35        UR                  S0 5      nUR                  S5      (       a  SU;  a  SU;  a  UR	                  S5        [        U5      S:H  UU[        U5      [        U5      [        UR                  S5      5      [        U5      S.S.$ s  snf s  snf )u   
验证模板与配置的一致性

Args:
    template_content: 模板内容
    category_config: 方向配置
    
Returns:
    验证结果，包含 valid、errors、warnings
stagesu   阶段数量不一致: 配置 u    个, Prompt u    个form_fieldsidz	category.zoutput.u$   Prompt 引用了未定义的变量: difficulty_rulesnameu$   难度级别可能不一致: 配置 u   , Prompt 中发现 output_configdockerDockeru8   配置需要 Docker 输出但 Prompt 中未提及 Dockerr   
)variables_countstages_counttotal_linestotal_chars)validerrorswarningsstats)
_extract_variables_extract_stagesr.   lenappendSYSTEM_VARIABLES
startswith_extract_difficultiessetsplit)r   r<   r@   rP   rQ   template_variablestemplate_stagesconfig_stagesfconfig_fieldsvardconfig_difficultiestemplate_difficultiesrG   s                  r    validate_template PromptCompiler.validate_template]   s     "445EF ../?@ (++Hb9}_!55MM0]1C0DMRUVeRfQggkl
 +:*=*=mR*PQ*PQ4*PQ%C'C7L7L,L~~k223>>);T;TOO&J3%$PQ & 3B2E2EFXZ\2]^2]Qy2]^ $ : :;K L S)<%=EZA[%[OO67J6KK^_t^uv
 (++OR@X&&8;K+KPX`pPpOOVW [A% #&'9#: #O 4"#3#9#9$#?@"#34		

 
	
' R _s   G?Hr   c           
         UR                   UR                  UR                  UR                  U R	                  UR                   5      U R                  US5      U R                  US5      U R                  U5      SS.	UR                  5       UR                  5       UR                  5       [        R                  " 5       R                  S5      S.nU(       a  UR                  U5        UR                  S5      nU(       an  U R                  X5      nU(       aV  UR                  SS	5      US'   UR                  S
S	5      US'   UR                  SSS/5      US'   UR                  SS5      US'   U$ )u   构建渲染上下文r   r   T)	rD   rF   icondescriptionknowledge_labelhas_language	has_scene	languagesno_commentsz%Y%m%d_%H%M%S)r   rB   rE   outputr   r   r      	max_countr   r   g      ?g      $@r   g333333?)rD   rF   rh   ri   _get_knowledge_label
_has_field_get_languages
get_stagesget_difficulty_rulesget_output_configr   nowstrftimeupdater.   _get_difficulty_rule)r   r   r%   r6   r   rules         r    r0   PromptCompiler._build_context   s;    kk  '33#'#<#<X[[#I $* E!__Xw?!00:#
 ))+ ( = = ?002!00A
& NN:& $5J00F/3xx/KGO,/3xxQ/GGO,-1XXmc4[-QGM*+/88K+EGK(r#   templater6   c                 p    UnU R                  X25      nU R                  X25      nU R                  X25      nU$ )u   渲染模板)_render_conditionals_render_loops_render_variables)r   r~   r6   results       r    r5   PromptCompiler._render_template   sB     **6; ##F4 ''8r#   c                 d   ^ ^ SnUU 4S jn[         R                  " X4U[         R                  S9nU$ )u   处理条件渲染z%\{\{#if\s+([^}]+)\}\}(.*?)\{\{/if\}\}c                    > U R                  S5      R                  5       nU R                  S5      nTR                  UT5      (       a  U$ g)N       )groupstrip_evaluate_condition)match	conditionr3   r6   r   s      r    replace_conditional@PromptCompiler._render_conditionals.<locals>.replace_conditional   sC    A,,.Ikk!nG ''	7;;r#   flagsresubDOTALL)r   r~   r6   patternr   r   s   ` `   r    r   #PromptCompiler._render_conditionals   s,     ;	 hbiiPr#   c                 d   ^ ^ SnUU 4S jn[         R                  " X4U[         R                  S9nU$ )u   处理循环渲染z)\{\{#each\s+([^}]+)\}\}(.*?)\{\{/each\}\}c                 d  > U R                  S5      R                  5       nU R                  S5      nT
R                  UT	5      nU(       a  [        U[        5      (       d  g/ n[        U5       H/  u  pV0 T	EXeS.EnT
R                  X'5      nUR                  U5        M1     SR                  U5      $ )Nr   r   r   )thisindex)	r   r   
_get_value
isinstancelist	enumerater   rV   r   )r   	items_keyitem_templateitemsresult_partsiitemloop_contextrenderedr6   r   s            r    replace_loop2PromptCompiler._render_loops.<locals>.replace_loop   s    A,,.I!KKNMOOIw7E
5$ 7 7L$U+D'D4D11-N##H-	 , 77<((r#   r   r   )r   r~   r6   r   r   r   s   ` `   r    r   PromptCompiler._render_loops   s,     ?	)" xryyIr#   c                 J   ^ ^ SnUU 4S jn[         R                  " X4U5      nU$ )u   处理变量插值z\{\{([^#/][^}]*)\}\}c                   > U R                  S5      R                  5       nSU;   aZ  UR                  S5      nUS   R                  5       nUS   R                  5       nTR                  UT5      nTR	                  XT5      $ SU;   a  SU;   a  TR                  UT5      $ TR                  UT5      nUc  U R                  S5      $ [        U5      $ )Nr   |r   ?:)r   r   r[   r   _apply_filter_evaluate_ternarystr)r   var_exprpartsvar_namefilter_exprvaluer6   r   s         r    replace_variable:PromptCompiler._render_variables.<locals>.replace_variable   s    {{1~++-H h s+ 8>>+#Ahnn.':))%== h3(?--h@@OOHg6E}{{1~%u:r#   )r   r   )r   r~   r6   r   r   r   s   ` `   r    r    PromptCompiler._render_variables   s&     *	( 8<r#   keyc                 x   U(       d  gUR                  S5      nUnU H  n[        U[        5      (       a  UR                  U5      nOi[        U[        5      (       a6  UR                  5       (       a!  [        U5      nU[        U5      :  a  XF   OSnO[        XE5      (       a  [        XE5      nO  gUb  M    g   U$ )u*   从上下文获取值，支持点号访问N.)
r[   r   dictr.   r   isdigitintrU   hasattrgetattr)r   r   r6   r   r   partr   s          r    r   PromptCompiler._get_value  s    		#D%&&		$E4((T\\^^D	(-E
(:%%,}  r#   r   c                    UR                  5       nUR                  S5      (       a  U R                  USS U5      (       + $ S H  nX1;   d  M
  UR                  US5      u  pEU R	                  UR                  5       U5      nUR                  5       n U(       a  [        U5      OSn[        U5      nUS:X  a  Xg:H  s  $ US:X  a  Xg:g  s  $ US	:X  a  Xg:  s  $ US
:X  a  Xg:  s  $ US:X  a  Xg:  s  $ US:X  d  M  Xg:*  s  $    U R	                  X5      nUc  g[        U[        5      (       a  U$ [        U[        [        [        45      (       a  [        U5      S:  $ [        U5      $ ! [        [        4 a     Nf = f)u   评估条件表达式znot    N)>=<=!===><r   r   r   r   r   r   r   r   F)r   rX   r   r[   r   floatr/   	TypeErrorr   boolr   r   r   rU   )	r   r   r6   opleftrightleft_val	right_valr   s	            r    r   "PromptCompiler._evaluate_condition+  sn   OO%	 ''//	!"wGGG 5B'oob!4??4::<A!KKM	2:uXH %i 0I :#004Z#003Y#//3Y#//4Z#004Z#001 56 	3=eT""LedD#.//u:>!E{1 #I. s   E""E54E5exprc                     [         R                  " SU5      nU(       a[  UR                  S5      R                  5       nUR                  S5      nUR                  S5      nU R	                  XB5      (       a  U$ U$ U$ )u   评估三元表达式z2(.+?)\s*\?\s*["\'](.+?)["\']\s*:\s*["\'](.+?)["\']r   r      )r   r   r   r   r   )r   r   r6   r   r   true_val	false_vals          r    r    PromptCompiler._evaluate_ternaryX  sj     NPTUA,,.I{{1~HAI''	;;  r#   r   r   c                    U(       d  gUR                  S5      nUS   R                  5       n[        U5      S:  a"  US   R                  5       R                  S5      OSnUS:X  a.  [        U[        5      (       a  UR                  S U 5       5      $ OXUS:X  a  [        [        U5      5      $ US	:X  a  [        U5      R                  5       $ US
:X  a  [        U5      R                  5       $ [        U5      $ )u   应用过滤器r   r   r   r   z"'r   c              3   8   #    U  H  n[        U5      v   M     g 7fN)r   ).0vs     r    	<genexpr>/PromptCompiler._apply_filter.<locals>.<genexpr>t  s     &=u!s1vvus   lengthupperlower)	r[   r   rU   r   r   r   r   r   r   )r   r   r   r   filter_name
filter_args         r    r   PromptCompiler._apply_filterh  s     !!#&Ahnn&69%j1nU1X^^%++E2"
& %&&!&=u&=== 'H$s5z?"G#u:##%%G#u:##%%5zr#   c                     Sn[         R                  " X!5      n[        5       nU HF  nUR                  5       nSU;  d  M  SU;   a  UR	                  S5      S   nUR                  U5        MH     [        U5      $ )u   从模板中提取变量名z"\{\{([^#/][^}|]*?)(?:\|[^}]*)?\}\}r   r   r   )r   findallrZ   r   r[   addr   )r   r~   r   matches	variablesr   ra   s          r    rS   !PromptCompiler._extract_variables~  si    7**W/E	E++-C#~#:))C.+Cc"  Ir#   c                 Z    Sn[         R                  " X!5      n[        [        U5      5      $ )u   从模板中提取阶段定义u$   ##?\s*阶段\s*(\d+(?:\.\d+)?)[：:])r   r   r   rZ   )r   r~   r   r   s       r    rT   PromptCompiler._extract_stages  s&     :**W/CL!!r#   c                 L    / nS H  nX1;   d  M
  UR                  U5        M     U$ )u   从模板中提取难度级别)u   入门u   简单u   中等u   困难u   地狱)rV   )r   r~   difficultiesdiffs       r    rY   $PromptCompiler._extract_difficulties  s0     FD##D) G r#   c                 6    SSSSSS.nUR                  US5      $ )u   获取知识点标签u   漏洞u   算法u   技术u   技能)webcryptoreversepwnmiscu	   知识点r.   )r   r$   labelss      r    rr   #PromptCompiler._get_knowledge_label  s-     
 zz+{33r#   field_idc                 N   ^ UR                  5       n[        U4S jU 5       5      $ )u!   检查方向是否有指定字段c              3   J   >#    U  H  oR                  S 5      T:H  v   M     g7f)rD   Nr   )r   r_   r   s     r    r   ,PromptCompiler._has_field.<locals>.<genexpr>  s     @Kq55;(*Ks    #)get_form_fieldsany)r   r   r   rC   s     ` r    rs   PromptCompiler._has_field  s"    ..0@K@@@r#   c                 .   UR                  5       nU Hw  nUR                  S5      S:X  d  M  UR                  S/ 5      nU(       d  M5  U Vs/ s H4  oUR                  S5      =(       d    UR                  S5      =(       d    UPM6     sns  $    / SQ$ s  snf )u!   获取方向支持的语言列表rD   r   optionsr   label)PythonPHPzNode.jsJavaGo)r  r.   )r   r   rC   fieldr  os         r    rt   PromptCompiler._get_languages  s}    ..0 Eyy*,))Ir27KRS7aEE'NAaeeGnAA7SS	 !
 :9 Ts   ;Br   c                 h    UR                  5       nU H  nUR                  S5      U:X  d  M  Us  $    g)u   获取指定难度的规则rF   N)rv   r.   )r   r   r   rulesr|   s        r    r{   #PromptCompiler._get_difficulty_rule  s5    --/Dxx:-  r#   c                 *   [         R                  R                  U R                  UR                  S5      n[         R                  R                  U5      (       a%  [        USSS9 nUR                  5       sSSS5        $ [         R                  R                  U R                  S5      n[         R                  R                  U5      (       a%  [        USSS9 nUR                  5       sSSS5        $ g! , (       d  f       N= f! , (       d  f       g= f)u   从文件系统加载模板z	CLAUDE.mdrutf-8encodingNr   )r   r   r   r   rD   existsopenread)r   r   template_pathr_   default_paths        r    r4   "PromptCompiler._load_file_template  s     T^^X[[+N77>>-((mS7;qvvx <; ww||DNNK@77>>,''lC':avvx ;:  <; ;: s   %C3D3
D
Doutput_pathc                 d   U R                  U5      nU(       d.  [        R                  R                  U R                  SU S35      n[        R
                  " [        R                  R                  U5      SS9  [        USSS9 nUR                  U5        SSS5        U$ ! , (       d  f       U$ = f)	u   
编译并保存 Prompt 到文件

Args:
    category_id: 方向 ID
    output_path: 输出路径（可选）
    
Returns:
    保存的文件路径
compiledz
_CLAUDE.mdT)exist_okwr  r  N)	r:   r   r   r   r   makedirsr   r  write)r   r$   r  r   r_   s        r    save_compiled_prompt#PromptCompiler.save_compiled_prompt  s     <<,'',,t~~zk]R\C]^K 	BGGOOK04@+sW5GGH 6  65 s   B  
B/)r   r   )$__name__
__module____qualname____firstlineno____doc__rW   r   r!   r   r   r:   r>   re   r   r0   r5   r   r   r   r   r   r   r   r   r   rS   rT   rY   rr   rs   rt   r   r{   r4   r%  __static_attributes__ r#   r    r   r      s    _# _$3 $DcN $c $N <@@c @ @*.sCx.@DG@(9
# 9
SRUX 9
[_`ceh`h[i 9
v"~ "4S> "]abegjbj]k "H tCH~ # S 4S> c &c DcN s 2# S#X 3 8c DcN s 0+S +4S> +d +Zc DcN s  3 S S ,3 49 " "S	 "c d3i 	4 	4 	4A> AS AT A
:~ :$s) :^  QYZ^_bdg_gZhQi N s   # QT  r#   r   )r+  r   jsonr   typingr   r   r   r   r   app.models.database.modelsr   r	   r   r-  r#   r    <module>r1     s-    
  	 , ,  EU Ur#   