From fbeb18ccec32808e71d4017281a08eddf7c55e00 Mon Sep 17 00:00:00 2001 From: devmrko Date: Wed, 8 Jul 2026 10:37:51 +0900 Subject: [PATCH] [Developer] align Select AI ORDS runtime route --- sql/adb/59_kb_select_ai_router_ords.sql | 100 ++++++++++++++++++++---- src/main/resources/application.yml | 2 +- 2 files changed, 86 insertions(+), 16 deletions(-) diff --git a/sql/adb/59_kb_select_ai_router_ords.sql b/sql/adb/59_kb_select_ai_router_ords.sql index cd4fbd4..38ce50c 100644 --- a/sql/adb/59_kb_select_ai_router_ords.sql +++ b/sql/adb/59_kb_select_ai_router_ords.sql @@ -16,6 +16,38 @@ SET ECHO OFF SET FEEDBACK ON SET DEFINE OFF +PROMPT === Creating local ORDS Team API wrapper === +CREATE OR REPLACE PACKAGE cb_select_ai_ords_api AUTHID DEFINER AS + FUNCTION run_team( + p_prompt IN CLOB, + p_conversation_id IN VARCHAR2 + ) RETURN CLOB; +END cb_select_ai_ords_api; +/ + +CREATE OR REPLACE PACKAGE BODY cb_select_ai_ords_api AS + FUNCTION run_team( + p_prompt IN CLOB, + p_conversation_id IN VARCHAR2 + ) RETURN CLOB AS + BEGIN + RETURN poc_2.kb_select_ai_router_api.run_team( + p_prompt => p_prompt, + p_conversation_id => p_conversation_id + ); + END run_team; +END cb_select_ai_ords_api; +/ + +SHOW ERRORS + +-- ORDS validates named PL/SQL references through its gateway account before +-- dispatching to the CB_ORDS parsing schema. These are the only two local +-- wrappers exposed to that account; both remain definer-rights and fixed in +-- scope (Bearer context setup and one fixed Team invocation). +GRANT EXECUTE ON cb_ords_handler_pkg TO ords_public_user; +GRANT EXECUTE ON cb_select_ai_ords_api TO ords_public_user; + PROMPT === Resetting only the KB Select AI Agent ORDS module === BEGIN ORDS.DELETE_MODULE(p_module_name => 'kb.select.ai.agent'); @@ -38,6 +70,28 @@ BEGIN p_pattern => 'run' ); + ORDS.DEFINE_TEMPLATE( + p_module_name => 'kb.select.ai.agent', + p_pattern => 'health' + ); + + ORDS.DEFINE_HANDLER( + p_module_name => 'kb.select.ai.agent', + p_pattern => 'health', + p_method => 'GET', + p_source_type => ORDS.source_type_plsql, + p_source => q'~ +BEGIN + :status_code := 200; + OWA_UTIL.MIME_HEADER('application/json', FALSE); + HTP.P('Cache-Control: no-store'); + OWA_UTIL.HTTP_HEADER_CLOSE; + HTP.P('{"status":"ok","team":"KB_SELECT_AI_ROUTER_TEAM"}'); +END; +~', + p_items_per_page => 0 + ); + ORDS.DEFINE_HANDLER( p_module_name => 'kb.select.ai.agent', p_pattern => 'run', @@ -51,6 +105,9 @@ DECLARE v_internal_conversation_id VARCHAR2(128); v_stakeholder_user_id VARCHAR2(4000); v_answer CLOB; + v_response CLOB; + v_error_code NUMBER; + v_error_message VARCHAR2(4000); BEGIN cb_ords_handler_pkg.set_vpd_context(:auth_header, :probe_id); @@ -76,37 +133,50 @@ BEGIN 'SHA256' ))); - v_answer := poc_2.kb_select_ai_router_api.run_team( - p_prompt => v_prompt, - p_conversation_id => v_internal_conversation_id - ); + -- ORDS validates static PL/SQL references before executing a Handler. + -- Invoke the local, fixed-scope Team wrapper through bound dynamic PL/SQL + -- so the runtime parser only sees the trusted local context package. + EXECUTE IMMEDIATE + 'BEGIN :result := cb_select_ai_ords_api.run_team(:prompt, :conversation_id); END;' + USING OUT v_answer, IN v_prompt, IN v_internal_conversation_id; + + SELECT JSON_OBJECT( + 'team' VALUE 'KB_SELECT_AI_ROUTER_TEAM', + 'conversationId' VALUE v_requested_conversation_id, + 'answer' VALUE v_answer + RETURNING CLOB + ) + INTO v_response + FROM dual; :status_code := 200; OWA_UTIL.MIME_HEADER('application/json', FALSE); HTP.P('Cache-Control: no-store'); OWA_UTIL.HTTP_HEADER_CLOSE; - APEX_JSON.OPEN_OBJECT; - APEX_JSON.WRITE('team', 'KB_SELECT_AI_ROUTER_TEAM'); - APEX_JSON.WRITE('conversationId', v_requested_conversation_id); - APEX_JSON.WRITE('answer', v_answer); - APEX_JSON.CLOSE_OBJECT; + HTP.P(v_response); cb_ords_handler_pkg.clear_vpd_context; EXCEPTION WHEN OTHERS THEN + v_error_code := SQLCODE; + v_error_message := SQLERRM; cb_ords_handler_pkg.clear_vpd_context; :status_code := CASE - WHEN SQLCODE IN (-20801, -20802) OR SQLCODE BETWEEN -40599 AND -40400 THEN 400 - WHEN SQLCODE BETWEEN -20199 AND -20100 THEN 403 + WHEN v_error_code IN (-20801, -20802) OR v_error_code BETWEEN -40599 AND -40400 THEN 400 + WHEN v_error_code BETWEEN -20199 AND -20100 THEN 403 ELSE 500 END; + SELECT JSON_OBJECT( + 'errorCode' VALUE v_error_code, + 'error' VALUE v_error_message + RETURNING CLOB + ) + INTO v_response + FROM dual; OWA_UTIL.MIME_HEADER('application/json', FALSE); HTP.P('Cache-Control: no-store'); OWA_UTIL.HTTP_HEADER_CLOSE; - APEX_JSON.OPEN_OBJECT; - APEX_JSON.WRITE('errorCode', SQLCODE); - APEX_JSON.WRITE('error', SQLERRM); - APEX_JSON.CLOSE_OBJECT; + HTP.P(v_response); END; ~', p_items_per_page => 0 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b74ee3d..f7152c9 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -40,7 +40,7 @@ backoffice: token: max-days: ${BACKOFFICE_TOKEN_MAX_DAYS:365} ords: - base-url: ${BACKOFFICE_ORDS_BASE_URL:https://yh0olybn5pqce4n-d8aukro81636mon0.adb.ap-seoul-1.oraclecloudapps.com/ords} + base-url: ${BACKOFFICE_ORDS_BASE_URL:https://g329127dfd380ad-kbaipoc.adb.ap-osaka-1.oraclecloudapps.com/ords} timeout: ${BACKOFFICE_ORDS_TIMEOUT_SECONDS:10}s agent-timeout: ${BACKOFFICE_ORDS_AGENT_TIMEOUT_SECONDS:180}s metadata-db: