
    P1i;                         d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
  ej                  e      Zddd	d
dddddd	ZddddddZdddddddddd d!d"d#Zd$ Zd% Zd& Zd' Zd( Zd+d)Zd,d*Zy)-z
Number Power analysis utilities for AI processing.

This module provides functions to prepare data for AI analysis of Number Power charts.
    N)timezone)PromptTemplate)LLMServiceFactory)filter_prompt_for_responseu   自信 (Confidence)u   妥协 (Compromise)u   选择 (Choice)u   成功 (Success)u   自由 (Freedom)u   平静 (Calmness)u   洞察 (Insight)u   利他 (Altruism)u#   机会/成功 (Opportunity/Success))	                        	   u   木u   火u   土u   金u   水woodfireearthmetalwateru	   鼠 (Rat)u   牛 (Ox)u   虎 (Tiger)u   兔 (Rabbit)u   龙 (Dragon)u   蛇 (Snake)u   马 (Horse)u
   羊 (Goat)u   猴 (Monkey)u   鸡 (Rooster)u	   狗 (Dog)u	   猪 (Pig))r   r   r   r	   r
   r   r   r   r   r   
      c                 6    t         j                  | d|  d      S )z#Get personality title for a number.z	Unknown ())NUMBER_PERSONALITYget)numbers    :/home/cursorai/projects/iching/ai/utils/number_analysis.pyget_personality_titler   5   s    !!&IfXQ*?@@    c                 <    dddddd}|j                  | d|        S )z+Get element profile description in Chinese.u-   生长性、适应性、灵活性、扩展性u0   热情、有活力、表现力强、充满活力u!   稳定、滋养、支持、扎根u'   精确、有结构、有条理、专注u'   流动、直觉、适应性强、灵活r   u   未知元素: )r   )elementprofiless     r   get_element_profiler#   9   s5     @B4::H <<>'!;<<r   c                     	 t        |       }t        j                  |d| d      S # t        t        f$ r	 d|  dcY S w xY w)z%Get Chinese zodiac name for a number.u   未知生肖 (r   )intZODIAC_NAMESr   
ValueError	TypeError)zodiac_numberr   s     r   get_zodiac_namer*   D   sP    1]#.(BCC	" 1a001s   $' ??c                    dddddd}dddddd}|| k(  ry||    |k(  r1d	t         j                  | |        d
t         j                  ||       dS ||   | k(  r1dt         j                  ||       dt         j                  | |        dS ||    |k(  r1d	t         j                  | |        dt         j                  ||       dS ||   | k(  r1dt         j                  ||       dt         j                  | |        dS y)zJGet the relationship between personal element and year element in Chinese.r   r   r   r   r   r   )r   r   r   r   r   u   同元素（相互增强）u   您的五行（u   ）生成年份五行（u   ）u   年份五行（u   ）生成您的五行（u   ）克制年份五行（u   ）克制您的五行（u   中性关系)ELEMENT_NAMESr   )personal_elementyear_element	generatescontrolss       r   get_element_relationshipr1   L   s    I H ''-	#	$	4 !2!23CEU!V WWop}  qB  qB  CO  Q]  q^  p_  _b  c  	c	<	 $4	4 !2!2<!N OOghuhyhy  {K  M]  i^  h_  _b  c  	c	"	#|	3 !2!23CEU!V WWop}  qB  qB  CO  Q]  q^  p_  _b  c  	c	,	#3	3 !2!2<!N OOghuhyhy  {K  M]  i^  h_  _b  c  	cr   c                     | rt        |       dk  rddddddddddd
S | d   | d    d| d    | d	   | d
   | d    d| d    | d   | d   | d    d| d    | d   | d   d
S )z Format number pairs for display.   zN/Az	N/A - N/A)
career_genescareer_processcareer_resultrelationship_genesrelationship_processrelationship_result
life_geneslife_processlife_resulthidden_giftr   r   z - r   r	   r
   r   r   r   r   r   r   r      )len)pairss    r   format_number_pairsrA   m   s    CJO!)""'$/#('  
 	
 a"1XJc%(4q#Ah#(8*Caz :$QxAh 8*Cb	{3RyRy r   c                    | j                   s1t        j                  d| j                   d| j                   d       y| j                   }|}|s.	 t
        j                  j                  dd      }|j                  }i }| j                  |d
<   | j                         |d<   | j                  j                  d      |d<   | j                  r| j                  j                  d      nd|d<   |j                  dd      |d<   |j                  dd      }t        |      |d<   t!        |      |d<   |j                  dd      }t"        j                  ||      |d<   t        |j                  dd            |d<   dj%                  d |j                  dg       D              |d<   dj%                  d |j                  d g       D              |d!<   |j                  d"d      }	t'        |	      |d#<   |j                  d$g       }
|
rdj%                  |
      nd%|d&<   |j                  d'i       }g }d}d}|rd}t)        d(      }|j+                         D ]w  \  }}t"        j                  t-        t"        j/                               t1        |      d)z
     d*|       }|j3                  | d+|        ||kD  r|}|}||k  sn|dkD  st|}|}y dj%                  |      |d,<   ||d-<   ||d.<   |j                  d/g       }t5        |      }|j+                         D ]  \  }}||d0| d1<    t7        j8                         j:                  }t        |      |d2<   |j                  d3d      }t        |      |d4<   |j                  d5d      }t"        j                  ||      |d6<   t=        ||      |d7<   |j+                         D ]E  \  }}|,t        j?                  d8| d9       |jA                  |d      }4|jA                  ||      }G |S # t
        j                  $ r t        j                  d       Y yt        $ r"}t        j                  d	|        Y d}~yd}~ww xY w):z
    Prepare a prompt for number power analysis.
    
    Args:
        person: Person instance with number_result
        custom_template: Optional custom template to use
        
    Returns:
        str: Formatted prompt
    z.Cannot prepare number analysis prompt: Person z (z) has no number_resultNr   active)divination_typestatusz,No active template found for number analysiszError retrieving template: z{{name}}z
{{gender}}z%Y-%m-%dz{{birth_date}}z%H:%Mu   未知z{{birth_time}}formulaz{{formula}}r   z{{personal_number}}z{{personality_title}}	number_5eunknownz{{personal_element}}headz{{head_number}}, c              3   2   K   | ]  }t        |        y wNstr.0ns     r   	<genexpr>z(prepare_number_prompt.<locals>.<genexpr>   s     3bDaqCFDa   no_nosz{{missing_numbers}}c              3   2   K   | ]  }t        |        y wrL   rM   rO   s     r   rR   z(prepare_number_prompt.<locals>.<genexpr>   s     3dDcqCFDcrS   have_nosz{{present_numbers}}zodiacz{{zodiac_name}}zodiac_boostu   无z{{zodiac_boost_numbers}}
number_5ecinfr   u   元素 : z{{element_counts}}z{{strongest_element}}z{{weakest_element}}pairs81z{{z}}z{{current_year}}year_numberz{{year_number}}year_5ez{{year_element}}z{{year_element_relationship}}zPlaceholder z has None value)!number_resultloggererrornameidr   objectsr   contentDoesNotExist	Exceptionget_gender_display
birth_datestrftime
birth_timerN   r   r,   joinr*   floatitemslistkeysr%   appendrA   r   nowyearr1   warningreplace)personcustom_templatenumber_datatemplate_contenttemplateereplacementspersonal_numberr-   r)   rX   element_countsformatted_element_countsstrongest_elementweakest_element	max_count	min_countelement_numcountelement_namer@   formatted_pairskeyvaluecurrent_yearr]   r.   placeholders                               r   prepare_number_promptr      s    Efkk]RTU[U^U^T__uvw &&K '	%--11(S[1\H'// L  &{{L!'!:!:!<L%+%6%6%?%?
%KL!"LRL]L]V%6%6%?%?%HckL!" #.//)X"FL!ooh2O*-o*>L&',A/,RL() #{I>+8+<+<=MO_+`L'( '*+//&(*K&LL"#*.))3bKOOT\^`Da3b*bL&'*.))3dKOOT^`bDc3d*dL&'  OOHh7M&5m&DL"#??>26LJVtyy/F\aL+, !__\26N! O	%L	"0"6"6"8K(,,T-2D2D2F-GKHXYZHZ-[_fgrfs]tuL$++|nBug,FGy !	$0!y UQY!	". #9 *.3K)LL%&,=L()*9L&' OOIr*E)%0O%++-
U).tC5%& . <<>&&L'*<'8L#$//-3K&)+&6L"#??9i8L'4'8'8|'TL#$ 5MM]_k4lL01 +002U=NN\+oFG/77XN/77UK 3 w ** 	LLGH 	LL6qc:;	s   -P (Q-Q5QQc           	         	 |r|s ddl m}  |d      }|xs |d   }|xs |d   }t        j                  d| j                   d| d|        	 t        j                  |      }t        j                  d	|j                  j                          |r*	 |j                  |       t        j                  d|        	 t        |       }t        j                  dt!        |       d       	 t        j                  d       |j#                  |dd      }t        j                  d|rt!        |      nd d       |s t        j                  d       t        d      	 |j%                         }	d}
ddl}	 |j)                  d|	|j*                        }|rn|j-                  d      j%                         }
|j/                  d d!|	|j*                  "      j%                         }	t        j                  d#t!        |
       d       |j)                  d$|	|j*                        }|r6|j-                  d      j%                         }|}	t        j                  d%       	 t1        j2                  |	      }|}	t        j                  d&       	 t9        |d|xs d-      }|}t        j                  d.| d/|        	 |	t;        |      ||d1}|
r|
|d2<   t        j                  d3d4j=                  |j?                                       	 || _         tC        jD                         | _#        d7| _$        | jK                  g d89       t        j                  d:| j                          | j@                  S # t        $ r=}t        j                  d
t        |              t        dt        |             d}~ww xY w# t        $ rC}t        j                  d| dt        |              t        d| dt        |             d}~ww xY w# t        $ r=}t        j                  dt        |              t        dt        |             d}~ww xY w# t        $ r=}t        j                  dt        |              t        dt        |             d}~ww xY w# t0        j4                  $ r,}t        j7                  d't        |              Y d}~Jd}~ww xY w# t        $ rY}t        j                  d(t        |              t        j                  d)|dd*  d+       t        d,t        |             d}~ww xY w# t        $ r8}t        j                  d0t        |              |xs d-}|xs d-}Y d}~d}~ww xY w# t        $ r=}t        j                  d5t        |              t        d6t        |             d}~ww xY w# t        $ r=}t        j                  d;t        |              t        d<t        |             d}~ww xY w# t        $ r6}t        j                  d=| j                   dt        |       d>?        d}~ww xY w)@a  
    Analyze a person's Number Power chart using AI.
    
    This function uses the active template from the database if available,
    otherwise falls back to the file system template.
    
    Args:
        person: Person object to analyze
        model_key: Optional model key to use (from settings.GROQ_MODELS or settings.OPENAI_MODELS)
        provider: Optional LLM provider to use ('groq' or 'openai')
        
    Returns:
        Dictionary with analysis results
    r   )get_ai_configr   providermodelz'Starting Number analysis for person id=z using provider=z, model=zCreated LLM service: zFailed to create LLM service: z"Could not initialize LLM service: NzChanged model to zFailed to change model to r[   zCould not change model to z6Prepared Number prompt using active template, length: z charactersz!Failed to prepare Number prompt: z!Could not prepare Number prompt: zRequesting LLM completiongffffff?i   )prompttemperature
max_tokenszReceived LLM response, length: zLLM returned empty responsezEmpty response from LLM servicezFailed to get LLM completion: z+Error getting completion from LLM service: z<think>(.*?)</think>r   z<think>.*?</think> )flagsz$Extracted thinking content, length: z```(?:json)?(.*?)```z Extracted content from backticksz$Successfully parsed analysis as JSONz*Analysis not valid JSON, using as string: z Failed to process LLM response: zRaw analysis: d   z...zError processing LLM response: rH   zUsed model: z, provider: z!Failed to get model information: )number_analysisr   r   r   thinkz+Prepared AI analysis dictionary with keys: rJ   z*Failed to prepare ai_analysis dictionary: z%Error preparing analysis dictionary: 	completed)number_ai_analysisnumber_analysis_timestampnumber_analysis_status)update_fieldsz1Successfully saved number analysis for person id=z*Failed to save analysis to person object: z#Error saving analysis to database: z"Error analyzing Number for person T)exc_info)&ai.utils.configr   r`   inforc   r   get_servicedebug	__class____name__rg   ra   rN   r'   change_modelr   r?   get_completionstripresearchDOTALLgroupsubjsonloadsJSONDecodeErrorrt   getattrr   rl   rp   r   r   rr   r   r   save)rv   	model_keyr   r   configllm_servicer{   r   raw_analysisanalysisthinking_contentr   thinking_matchbackticks_matchbackticks_content	json_datajson_err
used_modelused_providerai_analysiss                       r   analyze_numberr     s   cy5"8,F56*#5H!4VG_I=fii[HXYaXbbjktjuvw	L+77AKLL01F1F1O1O0PQR U((30<=	K*62FLLQRUV\R]Q^^ijk	ULL46&55 6 L
 LL:P\3|;Lbc:ddopq:; !BCC    %%'	IYY'>"))TN#1#7#7#:#@#@#B 66"7XRYY6W]]_CCHXDYCZZefg ii(?299UO$3$9$9!$<$B$B$D!,?@] JJx0	$CD	2 gy7MINJ$MLL<
|<OP
	O#+4V<)#	K  '7G$LLFtyyQ\QaQaQcGdFefg	M(3F%/7||~F,,7F)KK&sKtKKKFII;WX (((i  	LLL9#a&BCA#a&JKK	L  U9)Bs1vhOP #=i[3q6(!STTU  	KLL<SVHEF@QIJJ	K  	ULL9#a&BCJ3q6(STT	U* '' ]!KCPXM?[\\] 	ILL;CF8DELL>,t*<)=SAB>s1vhGHH	I  	2LL<SVHEF"/iJ$1	M	2  	OLLEc!fXNODSVHMNN	O  	MLLEc!fXNOB3q6(KLL	M  9&))Bs1vhOZ^_sJ  AX AM) X )N2 =-P +A1Q
 X 4C"S ,R .T: 3AU>  AW X )	N/28N**N//X 2	O>;>O99O>>X 	Q
8QQX 
	R8RRX S&!SS SS 	T7AT22T77X :	U;-U60X 6U;;X >	W8V??WX 	X8XXX 	Y1Y

YrL   )NN)__doc__loggingr   django.utilsr   	ai.modelsr   ai.services.factoryr   iching.utils.utilsr   	getLoggerr   r`   r   r,   r&   r   r#   r*   r1   rA   r   r    r   r   <module>r      s   
   ! $ 1 9			8	$ ,
   A	=1BBtlrr   