
    g5i                    p    d Z ddlmZ ddlZddlZddlmZ ddlmZ	 ddl
mZ  G d d      Z G d	 d
      Zy)z"Gemini AI client for KPI analysis.    )annotationsN)Any   )PromptLibraryc                  X    e Zd ZdZ	 	 d	 	 	 	 	 d	dZd
ddZ	 d
	 	 	 	 	 ddZddZddZy)GeminiClientzClient for Gemini AI API.c                    t        j                  |       t        j                  |      | _        || _        t        j
                  |ddd      | _        dddd	ddd
dddddg| _        y)zInitialize Gemini client.

        Args:
            api_key: Gemini API key.
            model: Model name to use.
            temperature: Temperature for generation (lower = more consistent).
        )api_keyg?(   i   )temperaturetop_ptop_kmax_output_tokensHARM_CATEGORY_HARASSMENT
BLOCK_NONE)category	thresholdHARM_CATEGORY_HATE_SPEECHHARM_CATEGORY_SEXUALLY_EXPLICITHARM_CATEGORY_DANGEROUS_CONTENTN)genai	configureGenerativeModelmodelr   GenerationConfiggeneration_configsafety_settings)selfr
   r   r   s       b/var/www/tkim.planitai.co.jp/gemegg/20251207-make-pdf-report/project/planitai-kpi/src/ai/client.py__init__zGeminiClient.__init__   sw     	(**51
& "'!7!7#"	"
 4,O4<P:V:V	 
    Nc                    |}|r| d| }| j                   j                  || j                  | j                        }|j                  S )zGenerate response from Gemini.

        Args:
            prompt: User prompt.
            system_prompt: Optional system prompt.

        Returns:
            Generated text response.
        z

)r   r   )r   generate_contentr   r   text)r   promptsystem_promptfull_promptresponses        r   generatezGeminiClient.generate2   sV     *O4x8K::.."44 00 / 
 }}r!   c                H    | j                  ||      }| j                  |      S )zGenerate JSON response from Gemini.

        Args:
            prompt: User prompt.
            system_prompt: Optional system prompt.

        Returns:
            Parsed JSON response.
        )r)   _parse_json_response)r   r%   r&   r$   s       r   generate_jsonzGeminiClient.generate_jsonH   s%     }}V]3((..r!   c                   t        j                  d|      }|r|j                  d      }n/t        j                  d|      }|r|j                  d      }n|ddS 	 t        j                  |      S # t        j
                  $ rJ | j                  |      }	 t        j                  |      cY S # t        j
                  $ r
 |ddcY cY S w xY ww xY w)zParse JSON from response text.

        Handles responses with markdown code blocks.

        Args:
            text: Response text.

        Returns:
            Parsed JSON dictionary.
        z```(?:json)?\s*([\s\S]*?)\s*```r   z\{[\s\S]*\}r   F)raw_responseparsed)researchgroupjsonloadsJSONDecodeError	_fix_json)r   r$   
json_matchjson_strfixeds        r   r+   z!GeminiClient._parse_json_responseY   s     YYA4H
!''*H >48J%++A. )->>	?::h''## 	?NN8,E?zz%(('' ?(,>>?	?s0   A0 0$CB,)C,C	CC		Cc                    t        j                  dd|      }t        j                  dd|      }t        j                  dd|      }|S )zTry to fix common JSON formatting issues.

        Args:
            json_str: Potentially malformed JSON string.

        Returns:
            Fixed JSON string.
        z,\s*}}z,\s*\]]z(\s*)(\w+)(\s*):z	\1"\2"\3:)r0   sub)r   r8   s     r   r6   zGeminiClient._fix_json|   sB     66(C266)S(3 66-|XFr!   )zgemini-2.0-flash-expg333333?)r
   strr   r>   r   floatNr%   r>   r&   
str | Nonereturnr>   r%   r>   r&   rB   rC   dict[str, Any])r$   r>   rC   rE   )r8   r>   rC   r>   )	__name__
__module____qualname____doc__r    r)   r,   r+   r6    r!   r   r   r      se    #
 , 	

 
 	
B2 %)// "/ 
	/"!?Fr!   r   c                  B    e Zd ZdZdddZd	dZdd
dZ	 d	 	 	 	 	 ddZy)MockGeminiClientzMock Gemini client for testing.Nc                (    |xs i | _         g | _        y)zwInitialize mock client.

        Args:
            responses: Dictionary mapping prompt keywords to responses.
        N)	responsescall_history)r   rN   s     r   r    zMockGeminiClient.__init__   s     #b')r!   c                "    || j                   |<   y)zSet response for a keyword.

        Args:
            keyword: Keyword to match in prompt.
            response: Response to return.
        N)rN   )r   keywordr(   s      r   set_responsezMockGeminiClient.set_response   s     #+wr!   c                   | j                   j                  |       | j                  j                         D ]>  \  }}|j	                         |j	                         v s't        j                  |d      c S  t        j                  ddd      S )zGenerate mock response.F)ensure_asciiMock responseTsummaryr/   )rO   appendrN   itemslowerr3   dumpsr   r%   r&   rQ   r(   s        r   r)   zMockGeminiClient.generate   st      (!%!5!5!7 	@GX}}&,,.0zz(??	@ zzoFGGr!   c                    | j                   j                  |       | j                  j                         D ])  \  }}|j	                         |j	                         v s'|c S  dddS )zGenerate mock JSON response.rU   TrV   )rO   rX   rN   rY   rZ   r\   s        r   r,   zMockGeminiClient.generate_json   s_     	  (!%!5!5!7 	 GX}}&,,.0	  +d;;r!   r@   )rN   z dict[str, dict[str, Any]] | None)rQ   r>   r(   rE   rC   NonerA   rD   )rF   rG   rH   rI   r    rR   r)   r,   rJ   r!   r   rL   rL      s;    )*+H %)<< "< 
	<r!   rL   )rI   
__future__r   r3   r0   typingr   google.generativeaigenerativeair   promptsr   r   rL   rJ   r!   r   <module>rd      s1    ( "  	  # "~ ~B+< +<r!   