create or replace function fnc_26ai_health( p_image_id in number, 
                                            p_source in varchar2, 
                                            p_comp_id in varchar2,
                                            p_credential in varchar2 default 'OCI_CRED')
return clob
as
/*

  Criado por: fernando.leal@oracle.com
  Data: Oct/2025
  Objetivo: demonstrar casos de uso do Oracle AI Database 26ai

  v1 - funcao principal de Heathcare, com similaridade e RAG - leal


    --
    -- Pre Req para Re-Rank: criamos nova credential para Cohere
    -- Podemos usar ReRank como ONNX atraves de https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/onnx-pipeline-models-reranking-pipeline.html
    --
    DECLARE
       jo json_object_t;
    BEGIN
       jo := json_object_t();
       jo.put('access_token', 'xxxxxxxxxxZBDKaQjPzB2Xdt8CkMtNz3KYRc1H0PjzRf6wkHxxxxxxxxxxxxx');  -- seu token Cohere. Gere Token em https://dashboard.cohere.com/
       DBMS_VECTOR.CREATE_CREDENTIAL(
              credential_name => 'COHERE_CRED',
              params => json(jo.to_string));
    END;

  -- PDFs

        BEGIN
           DBMS_CLOUD.GET_OBJECT(
           credential_name => 'OCI_CRED',
           object_uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/n/idi1o0a010nx/b/bucket-database-26ai/o/ecg.pdf',
           directory_name => 'DATA_PUMP_DIR');
        END;

        BEGIN
           DBMS_CLOUD.GET_OBJECT(
           credential_name => 'OCI_CRED',
           object_uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/n/idi1o0a010nx/b/bucket-database-26ai/o/raiox.pdf',
           directory_name => 'DATA_PUMP_DIR');
        END;


        BEGIN
           DBMS_CLOUD.GET_OBJECT(
           credential_name => 'OCI_CRED',
           object_uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/n/idi1o0a010nx/b/bucket-database-26ai/o/ressonancia2.pdf',
           directory_name => 'DATA_PUMP_DIR');
        END;

        BEGIN
           DBMS_CLOUD.GET_OBJECT(
           credential_name => 'OCI_CRED',
           object_uri => 'https://objectstorage.sa-saopaulo-1.oraclecloud.com/n/idi1o0a010nx/b/bucket-database-26ai/o/esoes_pele_dermatologia.pdf',
           directory_name => 'DATA_PUMP_DIR');
        END;


 -- Embedding com Cohere


     INSERT INTO "TB_26AI_HEALTH_VECTOR"
        select  'raiox.pdf' object_name,
                embed_id, 
                text_chunk, 
                embed_vector 
         from dual dt
                     CROSS JOIN TABLE(
                         dbms_vector_chain.utl_to_embeddings(
                             dbms_vector_chain.utl_to_chunks(
                                 dbms_vector_chain.utl_to_text(   to_blob(bfilename('DATA_PUMP_DIR', 'raiox.pdf' )) ), 
                                 -- dicas para chunking:  https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/explore-chunking-techniques-and-examples.html
                                 json('{"by":"words","max":"220","split":"sentence","normalize":"all", "overlap":50}')
                             ),
                             json('{
                                "provider": "ocigenai",
                                "credential_name": "OCI_CRED",
                                "url": "https://inference.generativeai.us-chicago-1.oci.oraclecloud.com/20231130/actions/embedText",
                                "model": "cohere.embed-v4.0"  }')
                         )
                     )  t
                     CROSS JOIN JSON_TABLE(
                         t.column_value, 
                         '$[*]' COLUMNS (
                             embed_id NUMBER PATH '$.embed_id',
                             text_chunk VARCHAR2(4000) PATH '$.embed_data',
                             embed_vector CLOB PATH '$.embed_vector'
                         )
                 ) AS et;

*/
   messages CLOB;
   params_genai CLOB;
   v_vector clob; 
   p_prompt clob;
   p_prompt2 clob;
   reranked_output json;
   output CLOB; 
begin

  SELECT json_value( fnc_26ai_embed_image_cohere(file_name, file_blob, p_credential , p_comp_id) , '$.embeddings[*].vector()')        
    INTO v_vector
    from TB_26AI_HEALTH
    where id = p_image_id;   

  for message_cursor in (

           SELECT embed_data , source
						FROM TB_26AI_HEALTH_VECTOR
						ORDER BY VECTOR_DISTANCE(EMBED_VECTOR, v_vector , EUCLIDEAN_SQUARED    )
						FETCH EXACT FIRST 10 ROWS ONLY    
                ) loop

      messages := messages || '"' || replace(replace(replace(replace(message_cursor.embed_data || ' (' || message_cursor.source || ')',chr(10),null),chr(13),null),'"',''),'''','') || '",' ;

  END LOOP;

     p_prompt := 'Atue como um especialista médico em ressonância magnética da coluna cervical, cardiologia, radiologia do crânio e dermatologia. 
     A partir da imagem gere laudos técnicos precisos e com respaldo médico a partir de uma destas especialiadades. 
     No caso de detectar algo grave, sugira que o usuário procure um especialista. Não dê resultados graves como Melanoma. 
     Nestes caso, oriente que procure-se um dermatologista.
     Sempre cite a origem encontrada em banco no caso de PDF vetorizado. Nunca cite nome do paciente ou do médico caso esteja visível na imagem.';

    -- cuidado com temperatura usando "." ou ","
    execute immediate('alter session set nls_numeric_characters=''.,'' '); 

   --
   -- ReRank (https://docs.oracle.com/en/database/oracle/oracle-database/23/vecse/use-reranking-better-rag-results.html)
   --
   params_genai := '{"provider": "cohere",
    "credential_name": "COHERE_CRED",
    "url": "https://api.cohere.com/v1/rerank",
    "model": "rerank-v3.5",
    "return_documents": true,
    "top_n": 1 }';

    reranked_output := dbms_vector_chain.rerank( p_prompt , json('{  "documents": [ ' || messages || '] }'), json(params_genai));

     -- cuidado com temperatura usando "." ou ","
    execute immediate('alter session set nls_numeric_characters=''.,'' '); 

    p_prompt2 := p_prompt || '. Informações obtidas para a imagem : ' || JSON_VALUE(  JSON_SERIALIZE(reranked_output), '$[0].content' );   

    -- rag
    output :=  fnc_26ai_rag_health(p_prompt2 , p_credential, p_image_id, p_comp_id);

    return output ;

end;
/