src/zgoog_agent_examples/zcl_gemini_agent_base.clas.abap (112 lines of code) (raw):
class ZCL_GEMINI_AGENT_BASE definition
public
abstract
create public .
public section.
types:
"! Structure for defining agent tools (ABAP Functions/Methods)
BEGIN OF ty_tool_parameter,
name TYPE string,
type TYPE string, " e.g., 'string', 'number', 'integer', 'boolean', 'array', 'object'
description TYPE string,
is_required TYPE abap_boolean,
END OF ty_tool_parameter .
types:
tt_tool_parameters TYPE STANDARD TABLE OF ty_tool_parameter WITH EMPTY KEY .
types:
BEGIN OF ty_tool_definition,
name TYPE string, " Name of the Function Module or Method (as registered)
description TYPE string,
parameters TYPE tt_tool_parameters,
implementation TYPE string, " Function Module name or Class-Method name (for reference)
END OF ty_tool_definition .
types:
tt_tool_definitions TYPE STANDARD TABLE OF ty_tool_definition WITH EMPTY KEY .
constants:
"! <p>Agent specific constants</p>
BEGIN OF model_keys,
gemini_flash TYPE /goog/model_key VALUE 'gemini-flash-2', " Or other desired model key
" gemini_pro TYPE /GOOG/MODEL_KEY VALUE 'gemini-1.5-pro-latest',
END OF model_keys .
methods PROCESS_PROMPT
importing
!IV_PROMPT type STRING
returning
value(R_RESULT) type STRING
raising
/GOOG/CX_SDK .
methods CLOSE .
"! <p>ABSTRACT: Subclass must provide the specific system instructions.</p>
"! @parameter r_result | The system instruction string<p></p>
methods GET_SYSTEM_INSTRUCTION
abstract
returning
value(R_RESULT) type STRING .
"! <p>ABSTRACT: Subclass must provide the specific tool definitions.</p>
"! @parameter r_result | Table of tool definitions | <p></p>
methods GET_TOOL_DEFINITIONS
abstract
returning
value(R_RESULT) type TT_TOOL_DEFINITIONS .
"! <p>ABSTRACT: Subclass must provide the model ID to use.</p>
"! @parameter r_result | The Google Cloud Model ID string |<p></p>
methods GET_MODEL_ID
abstract
returning
value(R_RESULT) type /GOOG/MODEL_KEY .
methods INITIALIZE_AGENT
raising
/GOOG/CX_SDK .
PROTECTED SECTION.
DATA mo_model TYPE REF TO /goog/cl_generative_model.
DATA mv_last_response TYPE string.
DATA mt_tools_registered TYPE tt_tool_definitions.
DATA mv_is_initialized TYPE abap_boolean VALUE abap_false ##NO_TEXT.
PRIVATE SECTION.
"! Helper method to register tools with the SDK model
"!
"! @parameter it_tool_definitions | Tool definitions
"! @raising /goog/cx_sdk | Google Cloud SDK Exception
METHODS register_tools
IMPORTING it_tool_definitions TYPE tt_tool_definitions
RAISING /goog/cx_sdk.
ENDCLASS.
CLASS ZCL_GEMINI_AGENT_BASE IMPLEMENTATION.
METHOD close.
" Ensure the model object exists and close the connection
IF me->mo_model IS BOUND.
mo_model->close( ).
CLEAR me->mo_model. " Release the reference
ENDIF.
ENDMETHOD.
METHOD initialize_agent.
IF mv_is_initialized = abap_true.
RETURN.
ENDIF.
DATA(lv_model_id) = get_model_id( ). " Call abstract method
DATA(lv_system_instruction) = get_system_instruction( ). " Call abstract method
DATA(lt_tools) = get_tool_definitions( ). " Call abstract method
TRY.
" 1. Create the Model Instance
me->mo_model = NEW #( iv_model_key = lv_model_id ).
" 2. Set System Instructions
mo_model->set_system_instructions( lv_system_instruction ).
" 3. Register Tools (Function Declarations) if any
IF lt_tools IS NOT INITIAL.
register_tools( lt_tools ).
mo_model->set_auto_invoke_sap_function( abap_true ).
ENDIF.
mv_is_initialized = abap_true.
CATCH /goog/cx_sdk INTO DATA(lx_sdk).
" Log exception or handle appropriately
RAISE EXCEPTION lx_sdk.
ENDTRY.
ENDMETHOD.
METHOD process_prompt.
CLEAR me->mv_last_response.
TRY.
" Generate content using the prompt
" The SDK handles the conversation history and potential tool calls internally
DATA(lo_response) = mo_model->generate_content( iv_prompt_text = iv_prompt ).
" Get the final text response
r_result = lo_response->get_text( ).
mv_last_response = r_result.
CATCH /goog/cx_sdk INTO DATA(lx_sdk).
" Log exception or handle appropriately
RAISE EXCEPTION lx_sdk.
ENDTRY.
ENDMETHOD.
METHOD register_tools.
LOOP AT it_tool_definitions ASSIGNING FIELD-SYMBOL(<fs_tool>).
DATA(lt_sdk_params) = VALUE /goog/cl_generative_model=>tt_parameter_properties( ).
" Convert tool parameters to SDK format
LOOP AT <fs_tool>-parameters ASSIGNING FIELD-SYMBOL(<fs_param>).
APPEND VALUE #( parameter_name = <fs_param>-name
type = <fs_param>-type
description = <fs_param>-description
is_required = <fs_param>-is_required )
TO lt_sdk_params.
ENDLOOP.
" Add the function declaration to the SDK model
mo_model->add_function_declaration( iv_name = <fs_tool>-name " Must match the FM name if using auto-invoke
iv_description = <fs_tool>-description
it_parameters = lt_sdk_params ).
ENDLOOP.
ENDMETHOD.
ENDCLASS.