Skip to Content
Technical Articles
Author's profile photo Monalisa Biswal

A Cool use of Open AI in SAP GUI Editor

Introduction

Here is a quick and effective example of using Open AI in SAP environment. In the example, developer can put pseudocode in the ABAP editor as comments and pass it on to Open AI and get back Open AI’s recommendations in the same editor.

Prerequisites

For this demo, will utilize one of the Open AI models trained on both natural and programming languages.

Below are the full details on the Codex models and how to work with it.

How to use the Codex models to work with code – Azure OpenAI Service | Microsoft Learn

To integrate open AI from SAP, will use Open AI ABAP SDK published in the following blog published by Gopal Nair:

Announcing – Microsoft AI SDK for SAP | SAP Blogs

I will be publishing more on how it will help with SAP based developments in future blogs.

This blog covers a simple integration with Open AI from SAP GUI classical editor.

Step-by-step

Steps to create dynamic Pattern:

  • Create a new pattern by going to Utilities->More Utilities->Edit Pattern->Create Pattern
  • Give a pattern name and click Ok.
  • Add *$&$EXIT in the Pattern.

Steps to handle Pattern Event in CMOD

  • Go to CMOD Tcode. Create a new project e.g. ZCOPILOT.
  • Select Enhancement Assignment. Assign SEUED001 Enhancement.
  • Go to Components. EXIT_SAPLOCAL_EDT1_001 gets triggered when pattern is selected in ABAP Editor
  • Create Include provided in this EXIT. Double click on Include and enter to allow system to create this Include.
  • Following code gets the source code of ABAP program from where the pattern is called.
data: field(40) type c value '(SAPLLOCAL_EDT1)CONTENT[]',
field_ind(40) type c value '(SAPLLOCAL_EDT1)CURSOR-NEW_INDEX'.
assign (field) to <fs_content>.
assign (field_ind) to <fs_ind>.
  • Now pass this code to open AI using ABAP SDK and get the code suggestion from the AI in response.
  • Add the code returned from AI to buffer internal table to make it available in the editor.
  • Full code for ZXSEUU26
DATA: lv_content(40) TYPE c  VALUE '(SAPLLOCAL_EDT1)CONTENT[]',
      lv_index(40)   TYPE  c VALUE '(SAPLLOCAL_EDT1)CURSOR-NEW_INDEX'.
data:
      sdk_instance  type ref to zif_peng_azoai_sdk,         "MS AI SDK for SAP Instance
      status_code   type i,                                 "Return Status Code
      status_reason type string,                            "Return Status Reason
      returnjson    type string,                            "Return JSON. The content of this JSON string is parsed and made available through ABAP data types.
      error         type zif_peng_azoai_sdk_types=>ty_error. "ABAP Type for Error
    data:
      chatcompl_input  type zif_peng_azoai_sdk_types=>ty_chatcompletion_input,
      chatcompl_output type zif_peng_azoai_sdk_types=>ty_chatcompletion_output.
     
    data:
      lv_api_url type string,
      lv_api_ver type string,
      lv_api_key type string,
      lv_depid   type string.
DATA: lv_buffer TYPE string,
      lv_code   TYPE string.
IF keyword = 'ZGPT'.

  ASSIGN (lc_content) TO <fs_content>.
  ASSIGN (lc_index) TO <fs_ind>.
IF <fs_content> IS ASSIGNED.
    IF <fs_ind> IS ASSIGNED AND <fs_ind> > 1.
      READ TABLE <fs_content> INDEX <fs_ind>  INTO lv_code.
      IF lv_code IS INITIAL.
        <fs_ind> = <fs_ind> - 1.
        READ TABLE <fs_content> INDEX <fs_ind>  INTO lv_code.
      ENDIF.
    ELSE.
      READ TABLE <fs_content> INDEX 1  INTO lv_code.
    ENDIF.
  ENDIF.
      lv_api_ver = api_ver.
      lv_api_url = api_url.
      lv_api_key  = api_key.
      lv_depid = depid.
       
      sdk_instance = zcl_peng_azoai_sdk_factory=>get_instance( )->get_sdk(
                                                              api_version = lv_api_ver
                                                              api_base    = lv_api_url
                                                              api_type    = zif_peng_azoai_sdk_constants=>c_apitype-azure
                                                              api_key     = lv_api_key
                                                            ).

*     Construct the prompt with system and user roles.
        append initial line to chatcompl_input-messages assigning field-symbol(<fs_message>).
        <fs_message>-role = zif_peng_azoai_sdk_constants=>c_chatcompletion_role-system.
        <fs_message>-content = search_role ."|You are an expert ABAP Developer|.
* Pass comments as prompt 
          append initial line to chatcompl_input-messages assigning <fs_message>.
          <fs_message>-role = zif_peng_azoai_sdk_constants=>c_chatcompletion_role-user.
          <fs_message>-content = lv_code.
*     Invoke Chat completion.
        sdk_instance->chat_completions( )->create(
          exporting
            deploymentid = lv_depid
            prompts      = chatcompl_input
          importing
            statuscode   = status_code                  " Status Code
            statusreason = status_reason                " HTTP status description
            json         = returnjson                   " JSON String returned from AI Resource
            response     = chatcompl_output
            error        = error                        " ABAP Ready error details
        ).
*     Response from open AI.
        if  chatcompl_output-choices is not initial.
         LOOP AT completions_output-choices ASSIGNING FIELD-SYMBOL(<fs_outputtext>).
          str_output = |{ str_output }{ <fs_outputtext>-text }|.
         ENDLOOP.
       endif.
 w_buffer =
   '*** Begin of AI Generated CODE***'.
      append w_buffer to buffer.
      w_buffer =
 '*----------------------------------------------------------------------*'.
      append w_buffer to buffer.

      if lv_response is not initial.
        split lv_response at cl_abap_char_utilities=>newline into table lt_tab. "cl_abap_char_utilities=>cr_lf
        loop at lt_tab into data(w_tab).
          w_buffer = w_tab.
          append w_buffer to buffer.
        endloop.
         w_buffer =
 '*----------------------------------------------------------------------*'.
  append w_buffer to buffer.
        w_buffer =
 '*** End of AI Generated CODE***'.
        append w_buffer to buffer.

  ENDIF.
ENDIF.
    CATCH zcx_peng_azoai_sdk_exception INTO DATA(_ex).
      MESSAGE _ex TYPE 'I'.
  ENDTRY.

Test Integration from Pattern

Test this integration using the dynamic pattern as shown below. Provide requirements in the comment and call dynamic pattern from Pattern popup to auto generate code.

Steps to add Menu exit and call Dynamic pattern.

You can add a menu exit to provide a shortcut for the pattern.

Go to CMOD and add a menu exit(SAPLS38E).

  • Implement EXIT_SAPLLOCAL_EDT1_002 function. Add following (in ZXSEUU25) to manually call pattern from menu exit.
constants: c_keyword type tse05-keyword value 'ZGPT'.
data: c_fieldname(40)     type c value '(SAPLLOCAL_EDT1)TDPARAM'. 
field-symbols: <fs_key>     type   rstxp-tdparam.
assign (c_fieldname) to <fs_key>.
<fs_key> = c_keyword."'ZGPT'.
perform insert_command in program sapllocal_edt1.
  • Based on SAP core version, above code for menu exit needs to be adjusted. You can debug pattern event from GUI to check how standard code is making call to pattern. Or You can always use Pattern to use this functionality.

Demo

Hope it inspires everyone to come up with more great ideas in integrating open AI.

 

Assigned Tags

      9 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Bennet van der Gryp
      Bennet van der Gryp

      Brilliant approach. Never would've thought to use an exit on a pattern.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      That is indeed a really smart approach.

      If only we could rely on AI producing quality code. https://blogs.sap.com/2023/02/15/how-chatgpt-answer-made-me-lose-my-time/

      Author's profile photo Bennet van der Gryp
      Bennet van der Gryp

      I'll probably implement it to add comments and documentation to code. Seems to be relatively good at that.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      There are two issues I have here, notwithstanding the brilliance of including it in the pattern user exit.

      First - if this is going to be universally useful, it will have to work in Eclipse.

      Second - there is a fundamental problem with AI generated code. It's called the Halting Problem and was proved to be unsolveable by Gödel. It means that you cannot guarantee any code is bug free. Which means you cannot guarantee any code generated by a computer is of high quality.

       

      https://blogs.sap.com/2023/02/15/how-chatgpt-answer-made-me-lose-my-time/

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      +1 to Matt's comments on AI-generated code but I admire sheer ingenuity here. 🙂

      Author's profile photo Kuang Chun Tien
      Kuang Chun Tien

      Hi, Ms.Biswal ,

      Can i Ask how did you use menu exit " ASK AI " to call your dynamic pattern?

      Author's profile photo Monalisa Biswal
      Monalisa Biswal
      Blog Post Author

      Hi Kuang,

      In the menu exit handler EXIT_SAPLLOCAL_EDT1_002, wrote following to mimic similar logic what SAP has for inserting pattern event

      constants: c_keyword type tse05-keyword value 'ZGPT'. "Provide pattern name here

      data: c_fieldname(40) type c value '(SAPLLOCAL_EDT1)TDPARAM'.

      field-symbols: <fs_key> type rstxp-tdparam.

      assign (c_fieldname) to <fs_key>.

      <fs_key> = c_keyword.

      perform insert_command in program sapllocal_edt1.

      Depending on SAP core version, you may need to adapt this code to call dynamic pattern from menu exit. Otherwise, you can use pattern option from GUI toolbar to test this integration.

      Author's profile photo Kuang Chun Tien
      Kuang Chun Tien

      Hi, Ms.Biswal,

      I am confused for this code:  "perform insert_command in program sapllocal_edt1."

      My understanding for dynamc pattern code is written in "EXIT_SAPLLOCAL_EDT1_001.

      how can i make a relation between "insert_command" subroutine in SAPLOCAL_EDT1  and EXIT_SAPLLOCAL_EDT1_001?

      the system responds a  run time error (ABAP Dump) , and the content is  "can't find this perform in SAPLOCAL_EDT1".

      thank you!

       

       

      Author's profile photo Monalisa Biswal
      Monalisa Biswal
      Blog Post Author

      I updated blog with details on How to test this functionality using pattern and steps for adding menu exit. The menu exit code may be different based on your SAP core version. You need to do little bit debugging to see if you can call pattern from menu exit. Please check and let me know if you still have any queries.