Event Callbacks
UC AI can send events to a PL/SQL procedure of your choice during a generate_text call. Use these events for:
- A streaming-style UI — show the assistant text or the tool call activity at once, and do not wait for the whole answer.
- Audit logging — record every tool call and its result, for compliance or to find a fault.
- Observability — group the events of one request id across providers, or across a long agent run.
An event callback is global to the session. Register it once. Every later generate_text call in that session then sends its events to your procedure, until you clear the callback.
Registering a callback
Section titled “Registering a callback”Your callback must be a top-level procedure that the schema can see. It must have this exact signature:
procedure my_ai_event_handler( p_request_id in varchar2, p_event_type in varchar2, p_event_data in clob -- JSON serialized payload);p_event_data is a CLOB and not a json_object_t, because execute immediate cannot bind a PL/SQL object type. For structured access, parse it with json_object_t.parse(p_event_data).
Register it with:
uc_ai.set_event_callback('MY_SCHEMA.MY_PKG.MY_AI_EVENT_HANDLER');And clear it with:
uc_ai.clear_event_callback;uc_ai.reset_globals keeps the registered callback name. You therefore do not register it again in each session.
Event types
Section titled “Event types”| Constant | Event type | When it fires |
|---|---|---|
uc_ai.c_event_assistant_text | assistant_text | The assistant returns a text content block |
uc_ai.c_event_assistant_reasoning | assistant_reasoning | The assistant returns a reasoning block |
uc_ai.c_event_tool_call | tool_call | Before a tool runs |
uc_ai.c_event_tool_result | tool_result | After a tool runs, with its result |
uc_ai.c_event_response_complete | response_complete | At the end of generate_text, with the final result object |
Every event is session-scoped. UC AI sets uc_ai.g_request_id at the start of each generate_text call, and clears it at the end. An event outside a generate_text call does not fire. This includes the time when you build the input messages yourself.
Example
Section titled “Example”This small handler writes each event to dbms_output:
create or replace package my_pkg is procedure on_ai_event( p_request_id in varchar2 , p_event_type in varchar2 , p_event_data in clob );end my_pkg;/
create or replace package body my_pkg is procedure on_ai_event( p_request_id in varchar2 , p_event_type in varchar2 , p_event_data in clob ) as l_data json_object_t; begin l_data := json_object_t.parse(p_event_data); dbms_output.put_line('[' || p_request_id || '] ' || p_event_type); case p_event_type when uc_ai.c_event_assistant_text then dbms_output.put_line(' text: ' || l_data.get_string('text')); when uc_ai.c_event_tool_call then dbms_output.put_line(' tool: ' || l_data.get_string('toolName')); when uc_ai.c_event_tool_result then dbms_output.put_line(' result: ' || l_data.get_clob('result')); else null; end case; end on_ai_event;end my_pkg;/Use it:
begin uc_ai.set_event_callback('MY_PKG.ON_AI_EVENT');
declare l_result json_object_t; begin l_result := uc_ai.generate_text( p_user_prompt => 'What is the email address of Jim?' , p_provider => uc_ai.c_provider_openai , p_model => uc_ai_openai.c_model_gpt_5_6_luna ); end;
uc_ai.clear_event_callback;end;/The output of a tool-calling path looks like this:
[A1B2C3...] tool_call tool: TT_GET_USERS[A1B2C3...] tool_result result: [{"user_id":4,"first_name":"Jim",...}][A1B2C3...] assistant_text text: jim.halpert@dundermifflin.com[A1B2C3...] response_completeError handling
Section titled “Error handling”If your callback raises an exception, UC AI catches it by default. A broken handler therefore never breaks an AI call. UC AI writes each failure to uc_ai_logger, with a backtrace for the diagnosis.
During development, an error in your handler must be visible. To abort the generate_text call on a callback error, set:
uc_ai.g_callback_fatal := true;uc_ai.reset_globals resets g_callback_fatal, but it does not reset g_event_callback.
Correlating events
Section titled “Correlating events”p_request_id is a correlation id for one call, as a hex GUID. Two sequential generate_text calls get two different request ids. Use this id to group the events of one AI call when several calls run in the same session, for example inside a multi-agent workflow.
During a call, you can also read the current request id from uc_ai.g_request_id.
Validation
Section titled “Validation”set_event_callback validates the procedure name with dbms_assert.qualified_sql_name. A malformed name such as not a valid name!!! therefore raises ORA-44003 or ORA-44004 before the first event.