Ë
    uPêjÂ*  ã                  ó¢   — d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	 ddl
mZ ddlmZ ddlmZ erdd	lmZ dd
lmZ dd„Zdd„Z G d„ de«      Zy)a¬  
Vertex AI RAG Engine Ingestion implementation.

Uses:
- litellm.files.acreate_file for uploading files to GCS
- Vertex AI RAG Engine REST API for importing files into corpus (via httpx)

Key differences from OpenAI:
- Files must be uploaded to GCS first (via litellm.files.acreate_file)
- Embedding is handled internally using text-embedding-005 by default
- Chunking configured via unified chunking_strategy in ingest_options
é    )ÚannotationsN)ÚTYPE_CHECKINGÚAnyÚFinal)Úget_secret_str)Úverbose_logger)ÚVertexAIRAGTransformation)ÚBaseRAGIngestion)ÚRouter)ÚRAGIngestOptionsc                ó    — | �t        | «      S dS )z#Cast config value to Optional[str].N)Ústr)Úvalues    úp/home/oem/CyberBrain26-unified/.venv/lib/python3.12/site-packages/litellm/llms/vertex_ai/rag_engine/ingestion.pyÚ_get_str_or_noner      s   € àÐ*Œ3ˆu‹:Ð4°Ð4ó    c                ó    — | €|S t        | «      S )z&Cast config value to int with default.)Úint)r   Údefaults     r   Ú_get_intr   "   s   € à€}ØˆÜˆu‹:Ðr   c                  ó–   ‡ — e Zd ZdZ	 d		 	 	 d
ˆ fd„Zdd„Z	 	 	 	 	 	 	 	 dd„Z	 	 	 	 dd„Zdd„Z	 	 	 	 dd„Z		 	 	 	 	 	 	 	 	 	 	 	 dd„Z
ˆ xZS )ÚVertexAIRAGIngestionaq  
    Vertex AI RAG Engine ingestion.

    Uses litellm.files.acreate_file for GCS upload, then imports into RAG corpus.

    Required config in vector_store:
    - vector_store_id: RAG corpus ID (required)

    Optional config in vector_store:
    - vertex_project: GCP project ID (uses env VERTEXAI_PROJECT if not set)
    - vertex_location: GCP region (default: us-central1)
    - vertex_credentials: Path to credentials JSON (uses ADC if not set)
    - wait_for_import: Wait for import to complete (default: True)
    - import_timeout: Timeout in seconds (default: 600)

    Chunking is configured via ingest_options["chunking_strategy"]:
    - chunk_size: Maximum size of chunks (default: 1000)
    - chunk_overlap: Overlap between chunks (default: 200)

    Authentication:
    - Uses Application Default Credentials (ADC)
    - Run: gcloud auth application-default login
    c                ó  •— t         ‰| �  ||¬«       | j                  j                  d«      | _        | j                  st        d«      ‚| j                  j                  d«      xs t        d«      | _        | j                  j                  d«      xs t        d«      xs d| _        | j                  j                  d	«      | _	        | j                  j                  d
«      xs t        j                  j                  d«      | _        | j                  st        d«      ‚| j                  j                  dd«      | _        t        | j                  j                  d«      d«      | _        | j                  st        d«      ‚y )N)Úingest_optionsÚrouterÚvector_store_idznvector_store_id (corpus ID) is required for Vertex AI RAG ingestion. Please provide an existing RAG corpus ID.Úvertex_projectÚVERTEXAI_PROJECTÚvertex_locationÚVERTEXAI_LOCATIONzus-central1Úvertex_credentialsÚ
gcs_bucketÚGCS_BUCKET_NAMEzkgcs_bucket is required for Vertex AI RAG ingestion. Set via vector_store config or GCS_BUCKET_NAME env var.Úwait_for_importTÚimport_timeoutiX  zpvertex_project is required for Vertex AI RAG ingestion. Set via vector_store config or VERTEXAI_PROJECT env var.)ÚsuperÚ__init__Úvector_store_configÚgetÚ	corpus_idÚ
ValueErrorr   r   r   r!   ÚosÚenvironr"   r$   r   r%   )Úselfr   r   Ú	__class__s      €r   r'   zVertexAIRAGIngestion.__init__B   sg  ø€ ô
 	‰Ñ¨¸vÐÔFð ×1Ñ1×5Ñ5Ð6GÓHˆŒØ�~Š~Üð<óð ð #×6Ñ6×:Ñ:Ð;KÓLÒrÔP^Ð_qÓPrˆÔà×$Ñ$×(Ñ(Ð):Ó;Òs¼~ÐNaÓ?bÒsÐfsð 	Ôð #'×":Ñ":×">Ñ">Ð?SÓ"TˆÔð ×2Ñ2×6Ñ6°|ÓDÒiÌÏ
É
ÏÉÐWhÓHiˆŒØ�ŠÜðJóð ð  $×7Ñ7×;Ñ;Ð<MÈtÓTˆÔÜ& t×'?Ñ'?×'CÑ'CÐDTÓ'UÐWZÓ[ˆÔð ×"Ò"ÜðKóð ð #r   c                óT   — d| j                   › d| j                  › d| j                  › �S )zGet full corpus resource name.z	projects/z/locations/z/ragCorpora/)r   r   r*   )r.   s    r   Ú_get_corpus_namez%VertexAIRAGIngestion._get_corpus_namek   s2   € à˜4×.Ñ.Ð/¨{¸4×;OÑ;OÐ:PÐP\Ð]a×]kÑ]kÐ\lÐmÐmr   c              ƒ  ó¨  K  — ddl }t        j                  j                  d«      }| j                  r| j                  t        j                  d<   	 |||f}t        j                  d|| j                  «       |j                  |dd| j                  | j                  | j                  ¬«      ƒ d{  –—† }|j                  }t        j                  d|«       ||�|t        j                  d<   S dt        j                  v rt        j                  d= S S 7 Œb# |�|t        j                  d<   w dt        j                  v rt        j                  d= w w xY w­w)	z™
        Upload file to GCS using litellm.files.acreate_file.

        Returns:
            GCS URI of the uploaded file (gs://bucket/path/file)
        r   Nr#   zEUploading file to GCS via litellm.files.acreate_file: %s (bucket: %s)Ú
assistantsÚ	vertex_ai)ÚfileÚpurposeÚcustom_llm_providerr   r   r!   zUploaded file to GCS: %s)Úlitellmr,   r-   r)   r"   r   ÚdebugÚacreate_filer   r   r!   ÚidÚinfo)	r.   Úfile_contentÚfilenameÚcontent_typer8   Úoriginal_bucketÚ
file_tupleÚresponseÚgcs_uris	            r   Ú_upload_file_to_gcsz(VertexAIRAGIngestion._upload_file_to_gcso   s7  è ø€ ó 	ô "$§¡§¡Ð0AÓ!BˆØ�?Š?Ø,0¯O©OŒB�J‰JÐ(Ñ)ð	2à!)¨<¸Ð FˆJä× Ñ ØWÐYaÐcg×crÑcrôð
 %,×$8Ñ$8ØØ$Ø$/Ø#×2Ñ2Ø $× 4Ñ 4Ø#'×#:Ñ#:ð %9ó %÷ ˆHð &Ÿ[™[ˆGÜ×ÑÐ :¸GÔDàð Ð*Ø0?”—
‘
Ð,Ò-Ø"¤b§j¡jÑ0Ü—J‘JÐ0Ñ1ð 1ð%ùð  Ð*Ø0?”—
‘
Ð,Ò-Ø"¤b§j¡jÑ0Ü—J‘JÐ0Ñ1ð 1üs1   ‚AEÁAD Â.DÂ/'D Ã;EÄD Ä<EÅEc              ƒ  ó  K  — 	 ddl m} ddl m}  || j                  | j
                  ¬«       | j                  «       }| j                  «       }t        j                  d|| j                  «       | j                  rA|j                  ||g|| j                  ¬«      }t        j                  d|j                  «       y|j!                  ||g|¬	«      }t        j                  d
«       y# t        $ r t        d«      ‚w xY w­w)zµ
        Import file into RAG corpus using the Vertex AI SDK.

        The REST API endpoint for importRagFiles is not publicly available,
        so we use the Python SDK.
        r   )Úinit©Úragú’vertexai.rag module not found. Vertex AI RAG requires google-cloud-aiplatform>=1.60.0. Install with: pip install 'google-cloud-aiplatform>=1.60.0')ÚprojectÚlocationzImporting %s into corpus %s)Úcorpus_nameÚpathsÚtransformation_configÚtimeoutz"Import complete: %s files imported)rL   rM   rN   zImport started asynchronouslyN)ÚvertexairF   rH   ÚImportErrorr   r   Ú_build_transformation_configr1   r   r9   r*   r$   Úimport_filesr%   r<   Úimported_rag_files_countÚimport_files_async)r.   rC   Úvertexai_initrH   rN   rL   rB   Ú_s           r   Ú_import_file_to_corpus_via_sdkz3VertexAIRAGIngestion._import_file_to_corpus_via_sdk¡   s  è ø€ ð	Ý6Ý$ñ 	˜d×1Ñ1¸D×<PÑ<PÕQð (,×'HÑ'HÓ'JÐà!×2Ñ2Ó4ˆÜ×ÑÐ:¸GÀTÇ^Á^ÔTà×Òà!×.Ñ.Ø'Ø�iØ&;Ø×+Ñ+ð	 /ó ˆHô ×ÑÐ DÀh×FgÑFgÕhð ×&Ñ&Ø'Ø�iØ&;ð 'ó ˆAô
 ×ÑÐ ?Õ@øôA ò 	Üð@óð ð	üs   ‚C?„C' �CC?Ã'C<Ã<C?c                ó  — 	 ddl m} ddlm} ddlm} t        «       }|j                   ||dz  | j                  «      «      }|d   d   }|d   d	   }|j                  |j                  ||¬
«      ¬«      S # t        $ r t        d«      ‚w xY w)zž
        Build Vertex AI TransformationConfig from unified chunking_strategy.

        Uses chunking_strategy from ingest_options (not vector_store).
        r   rG   rI   )Úcast)ÚRAGChunkingStrategyNÚchunking_configÚ
chunk_sizeÚchunk_overlap)r]   r^   )r\   )rP   rH   rQ   ÚtypingrZ   Úlitellm.types.ragr[   r	   Ú,transform_chunking_strategy_to_vertex_formatÚchunking_strategyÚTransformationConfigÚChunkingConfig)r.   rH   rZ   r[   Útransformationr\   r]   r^   s           r   rR   z1VertexAIRAGIngestion._build_transformation_configÐ   s·   € ð	Ý$õ 	 å9ä 9Ó ;ˆØ!/×!\Ñ!\ÙÐ$ tÑ+¨T×-CÑ-CÓDó"
ˆð ,Ð,=Ñ>¸|ÑLˆ
Ø.Ð/@ÑAÀ/ÑRˆà×'Ñ'Ø×.Ñ.Ø%Ø+ð /ó ð (ó 
ð 	
øô) ò 	Üð@óð ð	ús   ‚A6 Á6Bc              ƒ  ó   K  — y­w)z˜
        Vertex AI handles embedding internally - skip this step.

        Returns:
            None (Vertex AI embeds when files are imported)
        N© )r.   Úchunkss     r   ÚembedzVertexAIRAGIngestion.embedó   s   è ø€ ð ùs   ‚c              ƒ  ó‚  K  — |r|s,t        j                  d«       t        | j                  «      dfS | j	                  |||xs d¬«      ƒ d{  –—† }	 | j                  |¬«      ƒ d{  –—†  t        | j                  «      |fS 7 Œ67 Œ# t        $ r*}t        j                  d|«       t        d|› �«      |‚d}~ww xY w­w)a)  
        Store content in Vertex AI RAG corpus.

        Vertex AI workflow:
        1. Upload file to GCS via litellm.files.acreate_file
        2. Import file into RAG corpus via SDK
        3. (Optional) Wait for import to complete

        Args:
            file_content: Raw file bytes
            filename: Name of the file
            content_type: MIME type
            chunks: Ignored - Vertex AI handles chunking
            embeddings: Ignored - Vertex AI handles embedding

        Returns:
            Tuple of (corpus_id, gcs_uri)
        z<No file content or filename provided for Vertex AI ingestionNzapplication/octet-stream)r=   r>   r?   )rC   z)Failed to import file into RAG corpus: %sz'Failed to import file into RAG corpus: )
r   Úwarningr   r*   rD   rX   Ú	ExceptionÚerrorÚRuntimeErrorr   )r.   r=   r>   r?   rh   Ú
embeddingsrC   Úes           r   ÚstorezVertexAIRAGIngestion.storeÿ   sÒ   è ø€ ñ4 ¡8Ü×"Ñ"Ð#aÔbÜ# D§N¡NÓ3°TÐ9Ð9ð  $×7Ñ7Ø%ØØ%ÒCÐ)Cð  8ó  
÷ 
ˆð	UØ×5Ñ5¸gÐ5ÓF×FÐFô
 �4—>‘>Ó" GÐ+Ð+ð
øð GùÜò 	UÜ× Ñ Ð!LÈaÔPÜÐ!HÈÈÐLÓMÐSTÐTûð	UüsH   ‚AB?ÁBÁB?ÁB	 Á)BÁ*B	 Á.B?ÂB	 Â		B<Â%B7Â7B<Â<B?)N)r   r   r   zRouter | None)Úreturnr   )r=   Úbytesr>   r   r?   r   rr   r   )rC   r   rr   ÚNone)rr   r   )rh   ú	list[str]rr   úlist[list[float]] | None)r=   zbytes | Noner>   ú
str | Noner?   rw   rh   ru   ro   rv   rr   ztuple[str | None, str | None])Ú__name__Ú
__module__Ú__qualname__Ú__doc__r'   r1   rD   rX   rR   ri   rq   Ú__classcell__)r/   s   @r   r   r   )   sÎ   ø„ ñð6 !%ð'à(ð'ð õ'óRnð02àð02ð ð02ð ð	02ð
 
ó02ðd-Aàð-Að 
ó-Aó^!
ðF
àð
ð 
"ó
ð,,à"ð,,ð ð,,ð !ð	,,ð
 ð,,ð -ð,,ð 
'÷,,r   r   )r   r   rr   rw   )r   r   r   r   rr   r   )r{   Ú
__future__r   r,   r_   r   r   r   r8   r   Úlitellm._loggingr   Ú0litellm.llms.vertex_ai.rag_engine.transformationr	   Ú$litellm.rag.ingestion.base_ingestionr
   r   r`   r   r   r   r   rg   r   r   ú<module>r�      sF   ðñõ #ã 	ß ,Ñ ,å "Ý +Ý VÝ AáÝÝ2ó5ó
ôB,Ð+õ B,r   