Skip to content

Fixed bug in Explain. And added audit for profile name #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 20, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 88 additions & 13 deletions apex/select-ai-chat/f101.sql
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ prompt APPLICATION 101 - ADB Chat
-- Application Export:
-- Application: 101
-- Name: ADB Chat
-- Date and Time: 23:34 Thursday February 13, 2025
-- Date and Time: 19:45 Thursday February 20, 2025
-- Exported By: ADBCHAT
-- Flashback: 0
-- Export Type: Application Export
Expand Down Expand Up @@ -242524,6 +242524,7 @@ wwv_flow_imp_page.create_page_process(
' l_has_summary number;',
' l_prompt varchar2(4000);',
' v_profile_name varchar2(100);',
' v_summary_profile_name varchar2(100);',
' l_profile_names user_cloud_ai_profiles.profile_name%type := lower(APEX_UTIL.GET_PREFERENCE( ',
' p_preference => ''CLOUD_AI_PROFILE'',',
' p_user => :APP_USER));',
Expand All @@ -242532,9 +242533,18 @@ wwv_flow_imp_page.create_page_process(
' -- Is this a chat or ask database?',
' b_is_chat := case when upper(:P1_ASK_ADB) = ''Y'' then false else true end;',
'',
' -- Get the AI profile for this prompt. It will choose from the list of profiles that were selected by the user',
' v_profile_name:= ADB_CHAT.get_profile(',
' profile_names => JSON(l_profile_names),',
' prompt => :P1_PROMPT,',
' is_chat => b_is_chat',
' );',
'',
' v_profile_name := UPPER(v_profile_name);',
'',
' -- Generate response using prompt and profiles',
' j_response:= ADB_CHAT.generate(',
' profile_names => JSON(l_profile_names),',
' profile_name => v_profile_name,',
' prompt => :P1_PROMPT,',
' is_chat => b_is_chat',
' );',
Expand All @@ -242553,8 +242563,8 @@ wwv_flow_imp_page.create_page_process(
'',
' if l_has_summary = 0 then',
' -- Yes! Generate the summary b/c one does not exist.',
' -- get a profile to generate the response:',
' v_profile_name:= ADB_CHAT.get_profile(',
' -- get a profile to generate the response. ',
' v_summary_profile_name:= ADB_CHAT.get_profile(',
' profile_names => JSON(l_profile_names),',
' prompt => :P1_PROMPT,',
' is_chat => true',
Expand All @@ -242563,7 +242573,7 @@ wwv_flow_imp_page.create_page_process(
' l_prompt := dbms_cloud_ai.generate(',
' prompt => ''Rewrite as a short title : ''||:P1_PROMPT,',
' action => ''chat'',',
' profile_name => v_profile_name',
' profile_name => v_summary_profile_name',
' );',
'',
' ',
Expand All @@ -242572,8 +242582,8 @@ wwv_flow_imp_page.create_page_process(
' ',
' end if;',
'',
' insert into ADB_CHAT_PROMPTS (conv_id, prompt, response, asked_on, showsql) ',
' values (:p1_conv_id, :p1_prompt, c_response, systimestamp, c_sql);',
' insert into ADB_CHAT_PROMPTS (conv_id, profile_name, prompt, response, asked_on, showsql) ',
' values (:p1_conv_id, v_profile_name, :p1_prompt, c_response, systimestamp, c_sql);',
'',
'end;'))
,p_process_clob_language=>'PLSQL'
Expand Down Expand Up @@ -243663,6 +243673,9 @@ wwv_flow_imp_page.create_page(
' word-wrap: break-word;',
' font-family: inherit;',
' font-size: inherit;',
'}',
'.CodeMirror{',
'height : 45vh!important',
'}'))
,p_page_template_options=>'#DEFAULT#'
,p_protection_level=>'C'
Expand Down Expand Up @@ -243716,8 +243729,9 @@ wwv_flow_imp_page.create_page_plug(
'begin',
'',
'',
' SELECT SHOWSQL into l_showsql FROM ADB_CHAT_PROMPTS WHERE ID = :P3_CURRENT_ID;',
' SELECT PROMPT into l_prompt FROM ADB_CHAT_PROMPTS WHERE ID = :P3_CURRENT_ID;',
' SELECT SHOWSQL INTO l_showsql FROM ADB_CHAT_PROMPTS WHERE ID = :P3_CURRENT_ID;',
' SELECT PROMPT INTO l_prompt FROM ADB_CHAT_PROMPTS WHERE ID = :P3_CURRENT_ID;',
' SELECT PROFILE_NAME INTO l_profile_name FROM ADB_CHAT_PROMPTS WHERE ID = :P3_CURRENT_ID;',
'',
' -- You can''t get an explanation if the current model was changed to Vector Search',
' SELECT count(*) ',
Expand Down Expand Up @@ -244460,6 +244474,10 @@ wwv_flow_imp_shared.create_install_script(
,p_sequence=>10
,p_script_type=>'INSTALL'
,p_script_clob=>wwv_flow_string.join(wwv_flow_t_varchar2(
'drop table if EXISTS ADB_CHAT_PROMPTS;',
'drop table if EXISTS ADB_CHAT_CONVERSATIONS;',
'',
'',
' CREATE TABLE "ADB_CHAT_CONVERSATIONS" ',
' ( "ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE, ',
' "SUMMARY" VARCHAR2(4000 CHAR), ',
Expand All @@ -244472,6 +244490,7 @@ wwv_flow_imp_shared.create_install_script(
' CREATE TABLE "ADB_CHAT_PROMPTS" ',
' ( "ID" NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE NOKEEP NOSCALE NOT NULL ENABLE, ',
' "CONV_ID" NUMBER NOT NULL ENABLE, ',
' "PROFILE_NAME" VARCHAR2(400), ',
' "PROMPT" VARCHAR2(4000 CHAR), ',
' "RESPONSE" CLOB, ',
' "ASKED_ON" TIMESTAMP (6), ',
Expand All @@ -244485,6 +244504,7 @@ wwv_flow_imp_shared.create_install_script(
'',
' CREATE INDEX "ADB_CHAT_PROMPTS_I1" ON "ADB_CHAT_PROMPTS" ("CONV_ID") ',
' ;',
'',
'create or replace PACKAGE adb_chat AS',
' /**',
' * Generate SQL or return a response from the given prompt. Pass multiple profile names to if you want to search across multiple domains.',
Expand All @@ -244499,6 +244519,18 @@ wwv_flow_imp_shared.create_install_script(
' FUNCTION generate(profile_names JSON, prompt clob, is_chat boolean default false) RETURN JSON;',
'',
' /**',
' * Generate SQL or return a response from the given prompt. Pass a single profile name.',
' * If you do pass multiple profile names, you will need to provide a description when define the profile using dbms_cloud_ai.create_profile(description => ''xx'')',
' * @param profile_name : A single profile name that will be used to generate the response',
' * @param prompt : The question you would like to get an answer to',
' * @return : A JSON object with the fillowing attributes: ',
' sql : the generated SQL for a natural language query',
' response : the narrated response to a question. ',
' error : true | false. There was an error processing the request.',
' */',
' FUNCTION generate(profile_name VARCHAR2, prompt clob, is_chat boolean default false) RETURN JSON;',
'',
' /**',
' * Returns the profile name that will be used to process the prompt. See above for details',
' * This can be called independently. It is called by the generate function.',
' * @param profile_names : List of profile names in a JSON array ["profile1", "profile2"]',
Expand All @@ -244520,8 +244552,11 @@ wwv_flow_imp_shared.create_install_script(
'/',
'',
'',
'',
'',
'',
'create or replace PACKAGE BODY adb_chat AS',
' /**',
' /**',
' * Generate SQL or return a response from the given prompt. Pass multiple profile names to if you want to search across multiple domains.',
' * If you do pass multiple profile names, you will need to provide a description when define the profile using dbms_cloud_ai.create_profile(description => ''xx'')',
' * @param profile_names : List of profile names in a JSON array ["profile1", "profile2"]',
Expand All @@ -244541,8 +244576,45 @@ wwv_flow_imp_shared.create_install_script(
' -- Get the profile',
' v_profile_name := get_profile(profile_names, prompt, is_chat);',
'',
' -- Get the response',
' j_response := generate(v_profile_name, prompt, is_chat);',
'',
' -- Return the JSON doc',
' RETURN j_response; ',
' END;',
'',
'',
' /**',
' * Generate SQL or return a response from the given prompt. Pass a single profile name.',
' * If you do pass multiple profile names, you will need to provide a description when define the profile using dbms_cloud_ai.create_profile(description => ''xx'')',
' * @param profile_name : A single profile name that will be used to generate the response',
' * @param prompt : The question you would like to get an answer to',
' * @return : A JSON object with the fillowing attributes: ',
' sql : the generated SQL for a natural language query',
' response : the narrated response to a question. ',
' error : true | false. There was an error processing the request.',
' */',
' FUNCTION generate(profile_name VARCHAR2, prompt clob, is_chat boolean default false) RETURN JSON IS',
' v_profile_name varchar2(100);',
' v_action VARCHAR2(100);',
' j_response JSON;',
' c_response CLOB;',
' i_uses_vector_index NUMBER;',
' i_num_profiles NUMBER;',
' c_sql clob;',
' i_cursor NUMBER := dbms_sql.open_cursor;',
'',
' BEGIN',
' -- Ensure the profile is valid',
' v_profile_name := upper(profile_name);',
'',
' SELECT COUNT(profile_name)',
' INTO i_num_profiles',
' FROM user_cloud_ai_profiles',
' WHERE profile_name = v_profile_name;',
'',
' -- If CHAT, then simply call the model to get an answer',
' IF is_chat and v_profile_name is not null THEN',
' IF is_chat and v_profile_name is not null AND i_num_profiles !=0 THEN',
' c_response := dbms_cloud_ai.generate(',
' prompt => prompt,',
' action => ''chat'',',
Expand All @@ -244555,7 +244627,7 @@ wwv_flow_imp_shared.create_install_script(
' ''error'' VALUE false',
' RETURNING JSON);',
'',
' ELSIF v_profile_name IS NULL THEN',
' ELSIF v_profile_name IS NULL OR i_num_profiles = 0 THEN',
' -- There''s no AI profile, so error out.',
' j_response := JSON_OBJECT(',
' ''sql'' VALUE null,',
Expand Down Expand Up @@ -244590,7 +244662,7 @@ wwv_flow_imp_shared.create_install_script(
' ELSE',
' -- NL2SQL: generate the sql and then execute it',
' c_sql := dbms_cloud_ai.generate(',
' prompt => prompt || '' format column headings using camel case with spaces.'',',
' prompt => prompt,',
' action => ''showsql'',',
' profile_name => v_profile_name',
' );',
Expand Down Expand Up @@ -244766,6 +244838,9 @@ wwv_flow_imp_shared.create_install_script(
'END adb_chat;',
'/',
'',
'',
'',
'',
' '))
);
wwv_flow_imp_shared.create_install_object(
Expand Down