
    i                     p    d Z ddlZddlZddlmZmZ  ej                  e      ZdZ	dZ
g dZ G d d      Zy)	uU  
core/workers/lead_qualification_worker.py

Story 5.07 — LeadQualificationWorker: Qualification Script Runner

Uses Gemini Flash to generate 3 qualifying questions based on extracted
entities from an IntentSignal, then writes them to Redis for AIVA's next
utterance.

No SQLite. No real I/O in isolation — all dependencies are injected.
    N)AnyOptionalzgemini-2.0-flashz
A potential customer called about: {service} in {location}.
Generate 3 concise qualifying questions AIVA should ask next.
Focus on: urgency, budget range, specific requirements.
Return JSON: {{"questions": ["Q1", "Q2", "Q3"]}}
)z!When would you need this done by?z#Do you have a budget range in mind?z8Are there any specific requirements I should know about?c                   b    e Zd ZdZeZddZdedefdZdede	e
   fdZd	ed
e
ddfdZdefdZy)LeadQualificationWorkerz
    Worker that generates 3 qualifying questions via Gemini Flash
    and writes them to Redis for AIVA's next conversational turn.
    Nc                      || _         || _        y )N)_gemini_redis)selfgemini_clientredis_clients      ?/mnt/e/genesis-system/core/workers/lead_qualification_worker.py__init__z LeadQualificationWorker.__init__+   s    $"    entitiesreturnc                 x    |j                  dd      }|j                  dd      }t        j                  ||      S )z0Build the Gemini prompt from extracted entities.servicezgeneral serviceslocationz	your area)r   r   )getQUALIFICATION_PROMPTformat)r
   r   r   r   s       r   _build_promptz%LeadQualificationWorker._build_prompt/   s9    ,,y*<=<<
K8#**7X*NNr   response_textc                     	 t        j                  |      }|j                  dg       }t        |t              rt        |      dk\  r|dd S y# t         j                  t        t        f$ r Y yw xY w)z
        Parse Gemini response JSON and extract questions list.
        Returns list of 3 questions or None on parse failure.
        	questions   N)	jsonloadsr   
isinstancelistlenJSONDecodeErrorAttributeError	TypeError)r
   r   datar   s       r   _parse_questionsz(LeadQualificationWorker._parse_questions5   sh    
	::m,Db1I)T*s9~/B !}$$$ni@ 		s   A	A A.-A.
session_idr   c                     | j                   t        j                  d       yd| }| j                   j                  |dt	        j
                  |             t        j                  d|       y)z2Write qualification questions to Redis state hash.Nu(   No Redis client — skipping state writezaiva:state:qualification_questionsz-Wrote qualification_questions to Redis key=%s)r	   loggerwarninghsetr   dumpsdebug)r
   r'   r   keys       r   _write_to_redisz'LeadQualificationWorker._write_to_redisC   sW    ;;NNEFJ<(7I9NODcJr   c                   K   |j                   xs i }|j                  }d}| j                  H	 | j                  |      }| j                  j	                  |      }| j                  |j                        }|+t        j                  d|       t        | j                        }| j                  ||       d|iS # t        $ r"}t        j                  d|       d}Y d}~id}~ww xY ww)z
        1. Build prompt from intent.extracted_entities
        2. Call Gemini Flash for 3 qualifying questions
        3. Write questions to Redis aiva:state:{session_id}
        4. Return {"questions": ["Q1", "Q2", "Q3"]}
        Nu4   Gemini call failed (%s) — using fallback questionsz5Using fallback qualification questions for session=%sr   )extracted_entitiesr'   r   r   generate_contentr&   text	Exceptionr*   r+   infor    FALLBACK_QUESTIONSr0   )r
   intentr   r'   r   promptresponseexcs           r   executezLeadQualificationWorker.executeL   s      ,,2&&
	 <<#!++H5<<88@ 11(--@	 KKOQ[\T445I 	Z3Y''  !UWZ[ 	!s0   +C&AB8 5AC&8	C#CC&C##C&)NN)__name__
__module____qualname____doc__r7   r   dictstrr   r   r    r&   r0   r<    r   r   r   r   #   sk    
 ,#Od Os Oc htn K# K$ K4 K(t (r   r   )r@   r   loggingtypingr   r   	getLoggerr=   r*   GEMINI_MODELr   r7   r   rC   r   r   <module>rH      sH   
    			8	$!  G( G(r   