
    [7_i>                     d    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   " S S5      rg)u   
Prompt 模板编译器

将模板化的 Prompt 编译为最终的 AI 指导文件。
支持变量插值、条件渲染、循环渲染等功能。
    N)DictAnyListOptional)datetime)CategoryConfigc            	       |   \ 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)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     ;/Users/yu22x/Desktop/ge/ctf/app/services/prompt/compiler.py__init__PromptCompiler.__init__   s,     #^bggll277??83Lo&^    category_id
user_inputreturnc                     [        S5      e)u  
编译完整的 Prompt（已废弃，请使用 compile_from_template 或 PromptCompilerService）

Args:
    category_id: 方向 ID
    user_input: 用户输入的参数（可选，用于预览）
    
Returns:
    编译后的完整 Prompt 字符串
    
Note:
    此方法已废弃，prompt_templates 表已不再使用。
    请使用 compile_from_template() 方法并提供 template_content 参数，
    或使用 PromptCompilerService.compile_and_save_prompts() 方法。
u   PromptCompiler.compile() 方法已废弃，prompt_templates 表已不再使用。请使用 compile_from_template() 方法并提供 template_content 参数，或使用 PromptCompilerService.compile_and_save_prompts() 方法。)NotImplementedError)r   r#   r$   s      r   compilePromptCompiler.compile#   s      "S
 	
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 字符串
u   方向 'u   ' 不存在)r   queryget
ValueError_build_context_render_template)r   r*   r#   r$   r   contexts         r   compile_from_template$PromptCompiler.compile_from_template9   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*   r4   rD   rE   template_variablestemplate_stagesconfig_stagesfconfig_fieldsvardconfig_difficultiestemplate_difficultiesr;   s                  r   validate_template PromptCompiler.validate_templateM   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)	r8   r:   icondescriptionknowledge_labelhas_language	has_scene	languagesno_commentsz%Y%m%d_%H%M%S)r   r6   r9   outputr   r   r      	max_countr   r   g      ?g      $@r   g333333?)r8   r:   r\   r]   _get_knowledge_label
_has_field_get_languages
get_stagesget_difficulty_rulesget_output_configr   nowstrftimeupdater-   _get_difficulty_rule)r   r   r$   r1   r   rules         r   r/   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"   templater1   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   rr   r1   results       r   r0   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	conditioncontentr1   r   s      r   replace_conditional@PromptCompiler._render_conditionals.<locals>.replace_conditional   sC    A,,.Ikk!nG ''	7;;r"   flagsresubDOTALL)r   rr   r1   patternr   rw   s   ` `   r   rt   #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	enumeraterv   rJ   r   )r   	items_keyitem_templateitemsresult_partsiitemloop_contextrenderedr1   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   rr   r1   r   r   rw   s   ` `   r   ru   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   rO   r   _apply_filter_evaluate_ternarystr)r   var_exprpartsvar_namefilter_exprvaluer1   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   rr   r1   r   r   rw   s   ` `   r   rv    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.)
rO   r   dictr-   r   isdigitintrI   hasattrgetattr)r   r   r1   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   rL   r   rO   r   floatr.   	TypeErrorr   boolr   r   r   rI   )	r   r   r1   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   r1   r   r   true_val	false_vals          r   r    PromptCompiler._evaluate_ternaryH  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>d  s     &=u!s1vvus   lengthupperlower)	rO   r   rI   r   r   r   r   r   r   )r   r   r   r   filter_name
filter_args         r   r   PromptCompiler._apply_filterX  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   findallrN   r   rO   addr   )r   rr   r   matches	variablesr   rU   s          r   rG   !PromptCompiler._extract_variablesn  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   rN   )r   rr   r   r   s       r   rH   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   地狱)rJ   )r   rr   difficultiesdiffs       r   rM   $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   rf   #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)r8   Nr   )r   rS   r   s     r   r   ,PromptCompiler._has_field.<locals>.<genexpr>  s     @Kq55;(*Ks    #)get_form_fieldsany)r   r   r   r7   s     ` r   rg   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!   获取方向支持的语言列表r8   r   optionsr   label)PythonPHPzNode.jsJavaGo)r   r-   )r   r   r7   fieldr   os         r   rh   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   获取指定难度的规则r:   N)rj   r-   )r   r   r   rulesrp   s        r   ro   #PromptCompiler._get_difficulty_rule  s5    --/Dxx:-  r"   )r   r   )"__name__
__module____qualname____firstlineno____doc__rK   r   r    r   r   r(   r2   rY   r   r/   r0   rt   ru   rv   r   r   r   r   r   r   rG   rH   rM   rf   rg   rh   r   ro   __static_attributes__ r"   r   r
   r
      s    _# _
3 
DcN 
c 
. <@@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 r"   r
   )r  r   jsonr   typingr   r   r   r   r   app.models.database.modelsr   r
   r  r"   r   <module>r     s-    
  	 , ,  5] ]r"   