├── .abapgit.xml
├── .github
└── workflows
│ └── downport.yml
├── LICENSE
├── README.md
├── abaplint.json
├── changelog.txt
├── docs
├── Badi_ZLLM_IMPLEMENTATION.md
├── ClientConfiguration.md
├── Overview.md
├── Provider.md
├── Setup.md
├── TemplateParser.md
└── Usage.md
└── src
├── agent
├── package.devc.xml
├── zcl_llm_agent_base.clas.abap
├── zcl_llm_agent_base.clas.xml
├── zcl_llm_text_agent.clas.abap
├── zcl_llm_text_agent.clas.xml
├── zcx_llm_agent_error.clas.abap
├── zcx_llm_agent_error.clas.xml
├── zif_llm_agent.intf.abap
├── zif_llm_agent.intf.xml
├── zif_llm_agent_internal.intf.abap
├── zif_llm_agent_internal.intf.xml
├── zif_llm_agent_manager.intf.abap
├── zif_llm_agent_manager.intf.xml
└── zllm_agent.msag.xml
├── anthropic
├── package.devc.xml
├── zcl_llm_client_anthropic.clas.abap
└── zcl_llm_client_anthropic.clas.xml
├── aws
├── package.devc.xml
├── zcl_llm_client_aws.clas.abap
├── zcl_llm_client_aws.clas.xml
├── zcl_llm_client_aws_sigv4.clas.abap
├── zcl_llm_client_aws_sigv4.clas.testclasses.abap
└── zcl_llm_client_aws_sigv4.clas.xml
├── azureaif
├── package.devc.xml
├── zcl_llm_client_azureaif.clas.abap
└── zcl_llm_client_azureaif.clas.xml
├── azureoai
├── package.devc.xml
├── zcl_llm_client_azureoai.clas.abap
├── zcl_llm_client_azureoai.clas.xml
├── zcl_llm_so_js_azureoai.clas.abap
└── zcl_llm_so_js_azureoai.clas.xml
├── deepseek
├── package.devc.xml
├── zcl_llm_client_deepseek.clas.abap
└── zcl_llm_client_deepseek.clas.xml
├── gemini
├── package.devc.xml
├── zcl_llm_client_gemini.clas.abap
├── zcl_llm_client_gemini.clas.xml
├── zcl_llm_so_ge.clas.abap
├── zcl_llm_so_ge.clas.testclasses.abap
├── zcl_llm_so_ge.clas.xml
├── zcl_llm_tool_parser_gemini.clas.abap
├── zcl_llm_tool_parser_gemini.clas.testclasses.abap
└── zcl_llm_tool_parser_gemini.clas.xml
├── ollama
├── package.devc.xml
├── zcl_llm_client_ollama.clas.abap
└── zcl_llm_client_ollama.clas.xml
├── openai
├── package.devc.xml
├── zcl_llm_client_openai.clas.abap
├── zcl_llm_client_openai.clas.xml
├── zcl_llm_so_js_oa.clas.abap
└── zcl_llm_so_js_oa.clas.xml
├── openrouter
├── package.devc.xml
├── zcl_llm_client_openrouter.clas.abap
├── zcl_llm_client_openrouter.clas.xml
├── zcl_llm_so_js_or.clas.abap
└── zcl_llm_so_js_or.clas.xml
├── package.devc.xml
├── vertexai
├── package.devc.xml
├── zcl_llm_client_vertex_auth.clas.abap
├── zcl_llm_client_vertex_auth.clas.xml
├── zcl_llm_client_vertexai.clas.abap
├── zcl_llm_client_vertexai.clas.xml
├── zcl_llm_client_vertexai_s_area.clas.abap
├── zcl_llm_client_vertexai_s_area.clas.macros.abap
├── zcl_llm_client_vertexai_s_area.clas.xml
├── zcl_llm_client_vertexai_s_area.shma.xml
├── zcl_llm_client_vertexai_sr.clas.abap
├── zcl_llm_client_vertexai_sr.clas.xml
├── zcl_llm_options_vertexai.clas.abap
├── zcl_llm_options_vertexai.clas.testclasses.abap
└── zcl_llm_options_vertexai.clas.xml
├── z_llm_client.fugr.lz_llm_clientf00.abap
├── z_llm_client.fugr.lz_llm_clientf00.xml
├── z_llm_client.fugr.lz_llm_clienti00.abap
├── z_llm_client.fugr.lz_llm_clienti00.xml
├── z_llm_client.fugr.lz_llm_clientt00.abap
├── z_llm_client.fugr.lz_llm_clientt00.xml
├── z_llm_client.fugr.lz_llm_clienttop.abap
├── z_llm_client.fugr.lz_llm_clienttop.xml
├── z_llm_client.fugr.saplz_llm_client.abap
├── z_llm_client.fugr.saplz_llm_client.xml
├── z_llm_client.fugr.screen_0001.abap
├── z_llm_client.fugr.screen_0002.abap
├── z_llm_client.fugr.screen_0003.abap
├── z_llm_client.fugr.screen_0004.abap
├── z_llm_client.fugr.tableframe_z_llm_client.abap
├── z_llm_client.fugr.tableproc_z_llm_client.abap
├── z_llm_client.fugr.xml
├── zcl_llm_auth_disabled.clas.abap
├── zcl_llm_auth_disabled.clas.testclasses.abap
├── zcl_llm_auth_disabled.clas.xml
├── zcl_llm_call_logger.clas.abap
├── zcl_llm_call_logger.clas.testclasses.abap
├── zcl_llm_call_logger.clas.xml
├── zcl_llm_chat_request.clas.abap
├── zcl_llm_chat_request.clas.testclasses.abap
├── zcl_llm_chat_request.clas.xml
├── zcl_llm_client.clas.abap
├── zcl_llm_client.clas.xml
├── zcl_llm_client_base.clas.abap
├── zcl_llm_client_base.clas.xml
├── zcl_llm_common.clas.abap
├── zcl_llm_common.clas.testclasses.abap
├── zcl_llm_common.clas.xml
├── zcl_llm_default_impl.clas.abap
├── zcl_llm_default_impl.clas.xml
├── zcl_llm_encryption.clas.abap
├── zcl_llm_encryption.clas.testclasses.abap
├── zcl_llm_encryption.clas.xml
├── zcl_llm_factory.clas.abap
├── zcl_llm_factory.clas.testclasses.abap
├── zcl_llm_factory.clas.xml
├── zcl_llm_http_client_wrapper.clas.abap
├── zcl_llm_http_client_wrapper.clas.testclasses.abap
├── zcl_llm_http_client_wrapper.clas.xml
├── zcl_llm_options.clas.abap
├── zcl_llm_options.clas.testclasses.abap
├── zcl_llm_options.clas.xml
├── zcl_llm_so_js.clas.abap
├── zcl_llm_so_js.clas.testclasses.abap
├── zcl_llm_so_js.clas.xml
├── zcl_llm_statistics.clas.abap
├── zcl_llm_statistics.clas.xml
├── zcl_llm_template_parser.clas.abap
├── zcl_llm_template_parser.clas.testclasses.abap
├── zcl_llm_template_parser.clas.xml
├── zcl_llm_tool_calculator.clas.abap
├── zcl_llm_tool_calculator.clas.testclasses.abap
├── zcl_llm_tool_calculator.clas.xml
├── zcl_llm_tool_echo.clas.abap
├── zcl_llm_tool_echo.clas.xml
├── zcl_llm_tool_parser.clas.abap
├── zcl_llm_tool_parser.clas.testclasses.abap
├── zcl_llm_tool_parser.clas.xml
├── zcx_llm_authorization.clas.abap
├── zcx_llm_authorization.clas.xml
├── zcx_llm_http_error.clas.abap
├── zcx_llm_http_error.clas.xml
├── zcx_llm_template_parser.clas.abap
├── zcx_llm_template_parser.clas.xml
├── zcx_llm_validation.clas.abap
├── zcx_llm_validation.clas.xml
├── zif_llm_auth.intf.abap
├── zif_llm_auth.intf.xml
├── zif_llm_call_logger.intf.abap
├── zif_llm_call_logger.intf.xml
├── zif_llm_chat_request.intf.abap
├── zif_llm_chat_request.intf.xml
├── zif_llm_client.intf.abap
├── zif_llm_client.intf.xml
├── zif_llm_client_int.intf.abap
├── zif_llm_client_int.intf.xml
├── zif_llm_client_json_schema.intf.abap
├── zif_llm_client_json_schema.intf.xml
├── zif_llm_default_impl.intf.abap
├── zif_llm_default_impl.intf.xml
├── zif_llm_encryption.intf.abap
├── zif_llm_encryption.intf.xml
├── zif_llm_factory.intf.abap
├── zif_llm_factory.intf.xml
├── zif_llm_http_client_wrapper.intf.abap
├── zif_llm_http_client_wrapper.intf.xml
├── zif_llm_options.intf.abap
├── zif_llm_options.intf.xml
├── zif_llm_so.intf.abap
├── zif_llm_so.intf.xml
├── zif_llm_statistics.intf.abap
├── zif_llm_statistics.intf.xml
├── zif_llm_tool.intf.abap
├── zif_llm_tool.intf.xml
├── zif_llm_tool_parser.intf.abap
├── zif_llm_tool_parser.intf.xml
├── zllm_auth_enc.dtel.xml
├── zllm_auth_value.dtel.xml
├── zllm_call_log.tabl.xml
├── zllm_call_runtime.dtel.xml
├── zllm_char255.doma.xml
├── zllm_char255.dtel.xml
├── zllm_chat_example.prog.abap
├── zllm_chat_example.prog.screen_0100.abap
├── zllm_chat_example.prog.xml
├── zllm_choice.tabl.xml
├── zllm_client.msag.xml
├── zllm_client_config.tran.xml
├── zllm_clnt_config.tabl.xml
├── zllm_clnt_configs.tobj.xml
├── zllm_default_options.dtel.xml
├── zllm_defaults.enhs.xml
├── zllm_error.tabl.xml
├── zllm_f4_prov_class.shlp.xml
├── zllm_function_resp.tabl.xml
├── zllm_keyvalue.tabl.xml
├── zllm_keyvalues.ttyp.xml
├── zllm_model.doma.xml
├── zllm_model.dtel.xml
├── zllm_model.shlp.xml
├── zllm_msg.tabl.xml
├── zllm_msgs.ttyp.xml
├── zllm_provider.dtel.xml
├── zllm_provider_config.tran.xml
├── zllm_provider_disp.tabl.xml
├── zllm_provider_maintenance.prog.abap
├── zllm_provider_maintenance.prog.screen_0100.abap
├── zllm_provider_maintenance.prog.screen_0200.abap
├── zllm_provider_maintenance.prog.xml
├── zllm_provider_name.dtel.xml
├── zllm_providers.tabl.xml
├── zllm_request.tabl.xml
├── zllm_response.tabl.xml
├── zllm_role.doma.xml
├── zllm_role.dtel.xml
├── zllm_save_calls.dtel.xml
├── zllm_session_id.dtel.xml
├── zllm_statistics.tabl.xml
├── zllm_statistics_enabled.dtel.xml
├── zllm_supp_so.dtel.xml
├── zllm_supp_tools.dtel.xml
├── zllm_system.tabl.xml
├── zllm_system_conf.tran.xml
├── zllm_systems.tobj.xml
├── zllm_tokens_prompt.dtel.xml
├── zllm_tokens_resp.dtel.xml
├── zllm_tokens_total.dtel.xml
├── zllm_tool_call.tabl.xml
├── zllm_tool_calls.ttyp.xml
├── zllm_tools.ttyp.xml
└── zllm_usage.tabl.xml
/.abapgit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | E
6 | /src/
7 | PREFIX
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/workflows/downport.yml:
--------------------------------------------------------------------------------
1 | name: downport
2 | permissions:
3 | contents: write
4 | pull-requests: write
5 |
6 | on:
7 | push:
8 | branches: [main]
9 | workflow_dispatch:
10 |
11 | jobs:
12 | build_downpor_branch:
13 | runs-on: ubuntu-latest
14 | timeout-minutes: 10
15 | steps:
16 | - name: Checkout Repository
17 | uses: actions/checkout@v4
18 | with:
19 | ref: 702
20 |
21 | - name: Set up Node.js
22 | uses: actions/setup-node@v4
23 | with:
24 | node-version: '20'
25 |
26 | - run: npm ci
27 | - run: npm run prepare_downport
28 | - run: npm run delete_testclasses
29 | - run: npm run update_xml_files
30 | - run: npm run downport
31 |
32 | - name: Create Pull Request
33 | id: cpr
34 | uses: peter-evans/create-pull-request@v7
35 | with:
36 | branch: auto-downport
37 | title: "Auto Downport"
38 | commit-message: "Auto Downport"
39 | body: "Automated downport of changes from main"
40 | labels: "auto-merge"
41 |
42 | - name: Check outputs
43 | if: ${{ steps.cpr.outputs.pull-request-number }}
44 | env:
45 | GH_TOKEN: ${{ secrets.PAT }}
46 | run: |
47 | echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
48 | echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
49 | gh pr merge ${{ steps.cpr.outputs.pull-request-number }} --squash --auto --delete-branch
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 abap-ai Authors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/changelog.txt:
--------------------------------------------------------------------------------
1 | 2025-02-23 v0.20
2 | ----------------
3 |
4 | - Rework of the client interface, old one available as zif_llm_client_int
5 | - New ZCL_LLM_CLIENT is a wrapper around the old (now internal) interface, prefer this
6 | - Several bugfixes especially for Gemini client and tool calls
7 | - Features of the new client:
8 | - Simplified interface
9 | - Request now handled internally, one interface only
10 | - Send User Message with execute --> no add_message required
11 | - Auto-add LLM responses to chat history
12 | - Auto-retry in case of error (3 times by default, additional 10 seconds wait on 429/529)
13 | - Simpler execution of tools
--------------------------------------------------------------------------------
/docs/Badi_ZLLM_IMPLEMENTATION.md:
--------------------------------------------------------------------------------
1 | # BAdI ZLLM_IMPLEMENTATION
2 |
3 | Via this BAdI you can change the default implementation for mutliple basic client components with the most important one beeing implementing custom authorization checks.
4 |
5 | Use SE19 to create a new implementation for Enahncement Spot ZLLM_DEFAULTS. It is suggested to create a subclass of the default class to avoid issues in case it is extended at a later point in time.
6 |
7 | Methods:
8 |
9 | - ZIF_LLM_DEFAULT_IMPL~GET_JSON_IMPL\
10 | Allows you to define a different JSON implementation name (as string) if you cannot use /UI2/CL_JSON. For OLLAMA to properly run with tool use you must change the class_constructor to change the value of mc_json_type:
11 |
12 | ```abap
13 | "Need to refer to main class instead of local definition
14 | "CONCATENATE mc_json_type lo_json_type_descr->absolute_name INTO mc_json_type.
15 | DATA cl_ui2_json TYPE /ui2/cl_json=>json.
16 | DATA(ui2_json_desc) = cl_abap_typedescr=>describe_by_data( cl_ui2_json ).
17 | CONCATENATE mc_json_type ui2_json_desc->absolute_name INTO mc_json_type.
18 | ```
19 |
20 | - ZIF_LLM_DEFAULT_IMPL~GET_ENCRYPTION_IMPL\
21 | Allows you to use a custom encryption implementation if you cannot/don't want to use the default SSF implementation. Your custom impelementation must use the interface ZIF_LLM_ENCRYPTION.
22 | - ZIF_LLM_DEFAULT_IMPL~GET_CALL_LOGGER_IMPL - Custom Logger
23 | - ZIF_LLM_DEFAULT_IMPL~GET_STATISTICS_IMPL - Custom Statistics
24 | - ZIF_LLM_DEFAULT_IMPL~GET_AUTHORIZATION_IMPL\
25 | **Authorization Checks** - the default implementation does NO checks. This is intentional as I don't want to deliver a custom Auth Object that might conflict with existing ones or violate your conventions. Implement a custom class with the interface ZIF_LLM_AUTH and raise ZCX_LLM_AUTHORIZATION if the caller is not allowed to execute the function.
26 |
--------------------------------------------------------------------------------
/docs/ClientConfiguration.md:
--------------------------------------------------------------------------------
1 | # Client Configuration
2 |
3 | You can use transaction ZLLM_CLIENT_CONFIG or SM30 table ZLLM_CLNT_CONFIG.
4 |
5 | ## Configuration
6 |
7 | The table has the following fields which can be maintained as customzing:
8 |
9 | - Model: This is the model key you use in coding
10 | - Section LLM Client Configuration:
11 | - Provider Name: Select the configured [Provider](Provider.md)
12 | - Model: Provider-internal model name; in case of Azure OpenAI serivces this is the name of the deployment
13 | - Struct. Output?: Currently information only - if the model supports structured output, not validated at runtime
14 | - Tools Supported?: Currently information only - if the model supports tool output, not validated at runtime
15 | - Default Options: **Needs testing** - Text field that allows you to set options that will be passed as-is to the provider except they are overridden by code. Entries can be separated by ';', key/value separated by ':'. Values need to be enclosed in '"' if they are string values. Better maintenance options and examples will be provided in future.
16 |
17 | ## Provider specifics
18 |
19 | ### Google Vertex AI
20 |
21 | For models the internal model name must follow the format: /{location}/publishers/{publisher}/models/{modelid}
22 | Example: /europe-west3/publishers/google/models/gemini-1.5-flash
23 |
24 | ### AWS Bedrock
25 |
26 | Make sure to use proper model names, especially taking [cross-region](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles-support.html) inference profiles into account. Note that tool use currently seems flaky with differnt models using the converse API in a different way.
27 |
28 | ## Recommendations
29 |
30 | Your feedback and experience is highly appreciated to extend this list:
31 |
32 | - Setup default models for specific feature categories that can be exchanged without implementation changes, e.g.
33 | - Text output
34 | - Tool Calls
35 | - Structured Output
36 | - Avoid giving more details than necessary, e.g. in case of ollama you might use the model as llama3.2 which then is mapped to llama3.2:3b-instruct-q8_0
37 |
38 | ## System Configuration
39 |
40 | Via transaction ZLLM_SYSTEM_CONF or SM30 table ZLLM_SYSTEM statistics and tracing (saving http calls) can be enabled/disabled. Disabled by default.
41 |
42 | Currently this is a very rudimentary implementation which will be extended in future based on demand.
43 |
44 | - Table zllm_call_log contains the full http client request and response without headers and cookies - main use is for debugging
45 | - Table zllm_statistics contains basic call statistics with token counts
46 |
--------------------------------------------------------------------------------
/docs/Overview.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | [Setup](Setup.md) - details on mandatory initial setup steps.\
4 | [Prodiver Configuration](Provider.md) - Basic configuration to use providers like Ollama, OpenRouter or Azure OpenAI.\
5 | [Client Configuration](ClientConfiguration.md) - Customizing for the models.\
6 | [BAdI for basic topics like encrption, authorizations, etc](Badi_ZLLM_IMPLEMENTATION.md) - Especially relevant for implementing authorization checks.\
7 | [Usage Examples, Limitatons and Hints](Usage.md) - How to use the LLM Client. See also [llm_client_test](https://github.com/abap-ai/llm_client_tests) repository for an implemented example.
8 | [Template Parser](TemplateParser.md) - A Jinja like template parser with limited feature set. Aim is to make it easier to reuse prompts by having central templates.
9 |
--------------------------------------------------------------------------------
/docs/Setup.md:
--------------------------------------------------------------------------------
1 | # Setup
2 |
3 | ## Prerequisites
4 |
5 | - SAP NetWeaver 7.52 or higher (developed and tested on this release)
6 | - `/UI2/CL_JSON` PL12 or higher recommended
7 | - Alternative: Use [abap-to-json](https://github.com/SAP/abap-to-json) for pre-PL12 systems
8 |
9 | ## Installation
10 |
11 | 1. Install via [abapGit](https://github.com/abapGit/abapGit)
12 | 2. Optionally [abap-to-json](https://github.com/SAP/abap-to-json) if /UI2/CL_JSON is outdated. See [Badi_ZLLM_IMPLEMENTATION.md](Badi_ZLLM_IMPLEMENTATION.md) for details on required further steps if you use the abap-to-json implementation.
13 |
14 | ## Configuration
15 |
16 | 1. Setup TLS 1.2 properly as described for [abapGit](https://docs.abapgit.org/user-guide/setup/ssl-setup.html#sap-crypto-library)
17 | 2. Create RFC destinations for the providers see [Provider Documentation](Provider.md) for details
18 | - Ollama path prefix /api
19 | - OpenAI path prefix /v1
20 | - Openrouter path prefix /api/v1
21 | - AzureOpenAI path prefix /openai/deployments
22 | - Anthropic path prefix /v1
23 | 3. Add required SSL certificates in STRUST for the providers you want to use
24 | 4. Configure the provider via report ZLLM_PROVIDER_MAINTENANCE
25 |
26 | For details on the model configuration see [Client Configuration](ClientConfiguration.md).
27 |
28 | ## Encryption Setup
29 |
30 | Authorization values in the provider configuration are encrypted via SSF. Mandatory setup:
31 |
32 | - SE16 Table SSFAPPLIC create a new entry:
33 | - APPLIC: ZLLMCT (this name is mandatory, otherwise you need to update the code)
34 | - All B_XXX fields set as 'X'
35 | - Descript: LLM Client Credentials (you can use any description)
36 | - Transaction SSFA create a new entry for the application created above:
37 | - Hash Algorithm: SHA256
38 | - Encryption Algorithm: AES256-CBC
39 | - Keep all others as default
40 | - Transaction STRUST
41 | - Right click on the new entry named as you defined above and select create, use default settings
42 | - Hint: this is usually the last entry in the list
43 |
44 | Note that the application name is currently hardcoded, if you require a different value edit class zcl_llm_encryption. You might also open an issue to request this to be a configurable setting based on demand I might consider this, however as this is a quite rare setting in an ABAP system I do not expect any collisions with existing custom values.
45 |
--------------------------------------------------------------------------------
/src/agent/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Agents
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/agent/zcl_llm_agent_base.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_LLM_AGENT_BASE
7 | E
8 | LLM Agent Base - Abstract
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/agent/zcl_llm_text_agent.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcl_llm_text_agent DEFINITION
2 | PUBLIC
3 | INHERITING FROM zcl_llm_agent_base
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 |
8 | CLASS-METHODS class_constructor.
9 |
10 | METHODS:
11 | constructor
12 | IMPORTING
13 | model TYPE zllm_model DEFAULT 'llama3.2'
14 | tools TYPE zllm_tools OPTIONAL
15 | RAISING
16 | zcx_llm_agent_error.
17 |
18 | METHODS zif_llm_agent~execute REDEFINITION.
19 |
20 | PROTECTED SECTION.
21 | METHODS: initialize REDEFINITION.
22 | PRIVATE SECTION.
23 |
24 | " A default value should not exceed 132 characters, therefore we set it in constructor
25 | CLASS-DATA system_prompt TYPE string.
26 |
27 | ENDCLASS.
28 |
29 | CLASS zcl_llm_text_agent IMPLEMENTATION.
30 |
31 | METHOD constructor.
32 | TRY.
33 | DATA(client) = zcl_llm_factory=>get_client_int( model ).
34 | CATCH zcx_llm_authorization.
35 | " Currently no action
36 | ENDTRY.
37 | super->constructor( client = client tools = tools ).
38 | initialize( ).
39 | ENDMETHOD.
40 |
41 | METHOD zif_llm_agent~execute.
42 | " Execute with input text as prompt
43 | result = super->execute( prompt ).
44 | ENDMETHOD.
45 |
46 | METHOD initialize.
47 | " Add system prompt to memory
48 | add_to_memory_internal( VALUE #(
49 | msg-role = client->role_system
50 | msg-content = system_prompt ) ).
51 | ENDMETHOD.
52 |
53 | METHOD class_constructor.
54 | system_prompt =
55 | |You are a helpful expert assistant that happily solves the given task. |
56 | && |Your tone is business professional, concise and precise. |
57 | && |If tools are available, use them when appropriate to gather information needed for your response.|
58 | ##NO_TEXT.
59 | ENDMETHOD.
60 |
61 | ENDCLASS.
62 |
--------------------------------------------------------------------------------
/src/agent/zcl_llm_text_agent.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCL_LLM_TEXT_AGENT
7 | E
8 | Test response Agent
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/agent/zcx_llm_agent_error.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zcx_llm_agent_error DEFINITION
2 | PUBLIC
3 | INHERITING FROM cx_static_check
4 | FINAL
5 | CREATE PUBLIC .
6 |
7 | PUBLIC SECTION.
8 |
9 | INTERFACES if_t100_dyn_msg .
10 | INTERFACES if_t100_message .
11 |
12 | METHODS constructor
13 | IMPORTING
14 | !textid LIKE if_t100_message=>t100key OPTIONAL
15 | !previous LIKE previous OPTIONAL .
16 | PROTECTED SECTION.
17 | PRIVATE SECTION.
18 | ENDCLASS.
19 |
20 |
21 |
22 | CLASS zcx_llm_agent_error IMPLEMENTATION.
23 |
24 |
25 | METHOD constructor ##ADT_SUPPRESS_GENERATION.
26 | CALL METHOD super->constructor
27 | EXPORTING
28 | previous = previous.
29 | CLEAR me->textid.
30 | IF textid IS INITIAL.
31 | if_t100_message~t100key = if_t100_message=>default_textid.
32 | ELSE.
33 | if_t100_message~t100key = textid.
34 | ENDIF.
35 | ENDMETHOD.
36 | ENDCLASS.
37 |
--------------------------------------------------------------------------------
/src/agent/zcx_llm_agent_error.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCX_LLM_AGENT_ERROR
7 | E
8 | Error during agent execution
9 | 40
10 | 1
11 | X
12 | X
13 | X
14 |
15 |
16 |
17 | CONSTRUCTOR
18 | E
19 | CONSTRUCTOR
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/agent/zif_llm_agent_internal.intf.abap:
--------------------------------------------------------------------------------
1 | "!
2 | "! Only use it if you need to implement new providers. For end users using the new
3 | "! zif_llm_client interface is recommended which with zcl_llm_client implements
4 | "! a wrapper around this low level interface. Long-term internals might change.
5 | INTERFACE zif_llm_client_int
6 | PUBLIC.
7 |
8 | CONSTANTS: role_user TYPE zllm_role VALUE `user`,
9 | role_system TYPE zllm_role VALUE `system`,
10 | role_assistant TYPE zllm_role VALUE 'assistant',
11 | role_tool TYPE zllm_role VALUE `tool`.
12 |
13 | CLASS-METHODS:
14 | "!
15 | "! Get a new client based on the configuration
16 | "! @parameter client_config |
17 | "! @parameter provider_config |
18 | "! @parameter response |
19 | "! @raising zcx_llm_validation |
20 | get_client
21 | IMPORTING
22 | client_config TYPE zllm_clnt_config
23 | provider_config TYPE zllm_providers
24 | RETURNING VALUE(response) TYPE REF TO zif_llm_client_int
25 | RAISING zcx_llm_validation zcx_llm_authorization.
26 | METHODS:
27 | "!
28 | "! Execute the chat request
29 | "! @parameter request |
30 | "! @parameter response |
31 | chat IMPORTING request TYPE REF TO zif_llm_chat_request RETURNING VALUE(response) TYPE zllm_response,
32 | "!
33 | "! Create a new chat request
34 | "! @parameter response |
2 | INTERFACE zif_llm_client_json_schema
3 | PUBLIC .
4 | TYPES: BEGIN OF ENUM value_type,
5 | string,
6 | number,
7 | boolean,
8 | integer,
9 | END OF ENUM value_type.
10 |
11 | TYPES: BEGIN OF property_def,
12 | name TYPE string,
13 | type TYPE value_type,
14 | description TYPE string,
15 | allow_null TYPE abap_bool,
16 | END OF property_def,
17 | properties_def TYPE HASHED TABLE OF property_def WITH UNIQUE KEY name.
18 |
19 | TYPES: BEGIN OF object_def,
20 | name TYPE string,
21 | description TYPE string,
22 | properties TYPE properties_def,
23 | END OF object_def.
24 |
25 | TYPES: BEGIN OF array_def,
26 | name TYPE string,
27 | description TYPE string,
28 | properties TYPE properties_def,
29 | END OF array_def.
30 |
31 | CLASS-METHODS:
32 | "!
33 | "! Create a new instance.
34 | "! @parameter title |
JSON Schema Title
35 | "! @parameter result |
JSON Schema
36 | new_format IMPORTING title TYPE string RETURNING VALUE(result) TYPE REF TO zif_llm_client_json_schema.
37 | METHODS:
38 | "!
39 | "! Add one property (only one level supported).
40 | "! @parameter property |
Property to add
41 | "! @raising zcx_llm_validation |
42 | add_property IMPORTING property TYPE property_def RAISING zcx_llm_validation,
43 | "!
44 | "! Add an array of a specific object. Only one level supported.
45 | "! @parameter array |
6 | "! Returns an instance of the llm client for the given model.
7 | "! @parameter model |
Model Name
8 | "! @parameter response |
Client
9 | "! @raising zcx_llm_validation |
Validation Error - dynamic check
10 | "! @raising zcx_llm_authorization |
Authorization error
11 | CLASS-METHODS get_client
12 | IMPORTING model TYPE zllm_model
13 | RETURNING VALUE(response) TYPE REF TO zif_llm_client
14 | RAISING zcx_llm_validation zcx_llm_authorization.
15 |
16 |
17 | "!
Deprecated - Get an internal client
18 | "! This is only used internally, avoid using it in future directly.
19 | "! Might be changed or even removed in future without notice.
20 | "! @parameter model |
Model Name
21 | "! @parameter response |
Client
22 | "! @raising zcx_llm_validation |
Validation Error - dynamic check
23 | "! @raising zcx_llm_authorization |
Authorization error
24 | CLASS-METHODS get_client_int
25 | IMPORTING model TYPE zllm_model
26 | RETURNING VALUE(response) TYPE REF TO zif_llm_client_int
27 | RAISING zcx_llm_validation zcx_llm_authorization.
28 | ENDINTERFACE.
29 |
--------------------------------------------------------------------------------
/src/zif_llm_factory.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_LLM_FACTORY
7 | E
8 | LLM Factory
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 | GET_CLIENT
16 | E
17 | Get an LLM Client
18 |
19 |
20 | GET_CLIENT_INT
21 | E
22 | Deprecated - Get an internal client
23 |
24 |
25 |
26 |
27 | GET_CLIENT
28 | MODEL
29 | E
30 | Model Name
31 |
32 |
33 | GET_CLIENT
34 | RESPONSE
35 | E
36 | Client
37 |
38 |
39 | GET_CLIENT
40 | ZCX_LLM_AUTHORIZATION
41 | E
42 | Authorization error
43 |
44 |
45 | GET_CLIENT
46 | ZCX_LLM_VALIDATION
47 | E
48 | Validation Error - dynamic check
49 |
50 |
51 | GET_CLIENT_INT
52 | MODEL
53 | E
54 | Model Name
55 |
56 |
57 | GET_CLIENT_INT
58 | RESPONSE
59 | E
60 | Client
61 |
62 |
63 | GET_CLIENT_INT
64 | ZCX_LLM_AUTHORIZATION
65 | E
66 | Authorization error
67 |
68 |
69 | GET_CLIENT_INT
70 | ZCX_LLM_VALIDATION
71 | E
72 | Validation Error - dynamic check
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/src/zif_llm_http_client_wrapper.intf.abap:
--------------------------------------------------------------------------------
1 | "!
HTTP client wrapper
2 | INTERFACE zif_llm_http_client_wrapper
3 | PUBLIC.
4 | TYPES: BEGIN OF response,
5 | code TYPE sysubrc,
6 | message TYPE string,
7 | response TYPE string,
8 | http_response TYPE REF TO if_http_response,
9 | END OF response.
10 |
11 |
12 | "!
13 | "!
14 | "! @parameter client_config |
15 | "! @parameter provider_config |
16 | "! @parameter client |
17 | "! @raising zcx_llm_validation |
18 | CLASS-METHODS get_client
19 | IMPORTING client_config TYPE zllm_clnt_config
20 | provider_config TYPE zllm_providers
21 | RETURNING VALUE(client) TYPE REF TO zif_llm_http_client_wrapper
22 | RAISING zcx_llm_validation.
23 |
24 | "!
25 | "! Set a header value. Setting the same multiple time overwrites the header.
26 | "! @parameter name |
27 | "! @parameter value |
28 | "! @raising zcx_llm_validation |
29 | METHODS set_header
30 | IMPORTING !name TYPE string
31 | !value TYPE string
32 | RAISING zcx_llm_validation.
33 |
34 | "!
35 | "! Set the url to be called. The SM59 destination path will be prepended.
36 | "! @parameter url |
37 | "! @raising zcx_llm_validation |
38 | METHODS set_url
39 | IMPORTING url TYPE string
40 | RAISING zcx_llm_validation.
41 |
42 | "!
43 | "! Call the endpoint.
44 | "! @parameter request |
45 | "! @parameter session_id |
46 | "! @parameter msg |
47 | "! @parameter response |
48 | "! @raising zcx_llm_http_error |
49 | METHODS communicate
50 | IMPORTING !request TYPE string
51 | session_id TYPE zllm_session_id
52 | msg TYPE i
53 | RETURNING VALUE(response) TYPE response
54 | RAISING zcx_llm_http_error.
55 |
56 | "!
Close the client
57 | "!
58 | METHODS close_client.
59 |
60 | "!
Set a parameter
61 | "!
62 | "! @parameter name |
Parameter Name
63 | "! @parameter value |
Parameter Value
64 | METHODS set_parmeter IMPORTING !name TYPE string
65 | !value TYPE string.
66 |
67 | "!
Get all current request headers
68 | "!
69 | "! @parameter result |
Request Headers
70 | METHODS get_req_headers RETURNING VALUE(result) TYPE tihttpnvp.
71 | ENDINTERFACE.
72 |
--------------------------------------------------------------------------------
/src/zif_llm_http_client_wrapper.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_LLM_HTTP_CLIENT_WRAPPER
7 | E
8 | HTTP client wrapper
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 | CLOSE_CLIENT
16 | E
17 | Close the client
18 |
19 |
20 | GET_REQ_HEADERS
21 | E
22 | Get all current request headers
23 |
24 |
25 | SET_PARMETER
26 | E
27 | Set a parameter
28 |
29 |
30 |
31 |
32 | GET_REQ_HEADERS
33 | RESULT
34 | E
35 | Request Headers
36 |
37 |
38 | SET_PARMETER
39 | NAME
40 | E
41 | Parameter Name
42 |
43 |
44 | SET_PARMETER
45 | VALUE
46 | E
47 | Parameter Value
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/src/zif_llm_options.intf.abap:
--------------------------------------------------------------------------------
1 | "!
Options for the LLM call
2 | INTERFACE zif_llm_options
3 | PUBLIC .
4 | METHODS:
5 | "!
6 | "! Range [0, 2]
7 | "! @parameter temperature |
8 | set_temperature IMPORTING temperature TYPE decfloat16 RAISING zcx_llm_validation,
9 | "!
10 | "! > 0
11 | "! @parameter tokens |
12 | set_max_tokens IMPORTING tokens TYPE i RAISING zcx_llm_validation,
13 | "!
14 | "! Range [0, 1]
15 | "! @parameter top_p |
16 | set_top_p IMPORTING top_p TYPE decfloat16 RAISING zcx_llm_validation,
17 | "!
18 | "! Range [1, infinity]
19 | "! @parameter top_k |
20 | set_top_k IMPORTING top_k TYPE i RAISING zcx_llm_validation,
21 | "!
22 | "! Seed parameter for more repeatable output, integer only
23 | "! @parameter seed |
24 | set_seed IMPORTING seed TYPE i RAISING zcx_llm_validation,
25 | "!
26 | "! Range [-2, 2]
27 | "! @parameter frequency_penalty |
28 | set_frequency_penalty IMPORTING frequency_penalty TYPE decfloat16 RAISING zcx_llm_validation,
29 | "!
30 | "! Range [-2, 2]
31 | "! @parameter presence_penalty |
32 | set_presence_penalty IMPORTING presence_penalty TYPE decfloat16 RAISING zcx_llm_validation,
33 | "!
34 | "! Range [0, 1]
35 | "! @parameter min_p |
36 | set_min_p IMPORTING min_p TYPE decfloat16 RAISING zcx_llm_validation,
37 | "!
38 | "! Range [0, 1]
39 | "! @parameter top_a |
40 | set_top_a IMPORTING top_a TYPE decfloat16 RAISING zcx_llm_validation,
41 | "!
42 | "! Key-Value list of parameters that will be given to the model.
43 | "! @parameter parameters |
44 | set_custom_parameters IMPORTING parameters TYPE zllm_keyvalues,
45 | "!
46 | "! Get all parameters for the call
47 | "! @parameter parameters |
48 | get_paramters RETURNING VALUE(parameters) TYPE zllm_keyvalues.
49 | ENDINTERFACE.
50 |
--------------------------------------------------------------------------------
/src/zif_llm_options.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_LLM_OPTIONS
7 | E
8 | Options for the LLM call
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/zif_llm_so.intf.abap:
--------------------------------------------------------------------------------
1 | "!
Structured Output support
2 | INTERFACE zif_llm_so
3 | PUBLIC.
4 | TYPES: BEGIN OF def_description,
5 | fieldname TYPE string,
6 | description TYPE string,
7 | enum_values TYPE string_table,
8 | END OF def_description.
9 | TYPES def_descriptions TYPE STANDARD TABLE OF def_description WITH KEY fieldname.
10 |
11 | "!
12 | "! Set the schema for the structured output.
13 | "! @parameter data_desc |
CL_ABAP_DATADESCR reference based on the datatype to be used
14 | "! @parameter description |
Field descriptions for more details
15 | "! @raising zcx_llm_validation |
16 | METHODS set_schema
17 | IMPORTING
18 | data_desc TYPE REF TO cl_abap_datadescr
19 | description TYPE def_descriptions OPTIONAL
20 | RAISING
21 | zcx_llm_validation.
22 |
23 | "!
24 | "! Get the converted schema
25 | "! @parameter result |
26 | METHODS get_schema
27 | RETURNING VALUE(result) TYPE string.
28 |
29 | "!
30 | "! Mostly used internally to get the data type definition
31 | "! @parameter result |
32 | METHODS get_datatype RETURNING VALUE(result) TYPE REF TO cl_abap_datadescr.
33 |
34 | ENDINTERFACE.
35 |
--------------------------------------------------------------------------------
/src/zif_llm_so.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_LLM_SO
7 | E
8 | Structured Output support
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 | SET_SCHEMA
16 | DATA_DESC
17 | E
18 | CL_ABAP_DATADESCR reference based on the datatype to be used
19 |
20 |
21 | SET_SCHEMA
22 | DESCRIPTION
23 | E
24 | Field descriptions for more details
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/zif_llm_statistics.intf.abap:
--------------------------------------------------------------------------------
1 | "!
2 | INTERFACE zif_llm_tool
3 | PUBLIC.
4 | CONSTANTS type_function TYPE string VALUE `function`.
5 |
6 | TYPES: BEGIN OF tool_parameters,
7 | data_desc TYPE REF TO cl_abap_datadescr,
8 | descriptions TYPE zif_llm_tool_parser=>def_descriptions,
9 | END OF tool_parameters.
10 |
11 | TYPES: BEGIN OF tool_details,
12 | name TYPE string,
13 | description TYPE string,
14 | type TYPE string,
15 | parameters TYPE tool_parameters,
16 | END OF tool_details.
17 |
18 | TYPES: BEGIN OF tool_result,
19 | data TYPE REF TO data,
20 | tool_call_id TYPE string,
21 | name TYPE string,
22 | END OF tool_result.
23 |
24 | "!
25 | "! Get the result of the tool call
26 | "! @parameter result |
27 | METHODS get_result RETURNING VALUE(result) TYPE tool_result.
28 |
29 | "!
30 | "! Returns tool details required to parse it as tool for the LLM
31 | "! @parameter result |
Tool details
32 | METHODS get_tool_details RETURNING VALUE(result) TYPE tool_details.
33 |
34 |
35 | "!
36 | "! Execute the tool.
37 | "! @parameter data |
LLM Model Tool Call response
38 | "! @parameter tool_call_id |
LLM Model Tool Call ID
39 | "! @parameter result |
Execution result
40 | METHODS execute IMPORTING data TYPE REF TO data
41 | tool_call_id TYPE string
42 | RETURNING VALUE(result) TYPE tool_result.
43 |
44 | ENDINTERFACE.
45 |
--------------------------------------------------------------------------------
/src/zif_llm_tool.intf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZIF_LLM_TOOL
7 | E
8 | Tool (Function) Call
9 | 2
10 | 1
11 | X
12 |
13 |
14 |
15 | EXECUTE
16 | DATA
17 | E
18 | LLM Model Tool Call response
19 |
20 |
21 | EXECUTE
22 | RESULT
23 | E
24 | Execution result
25 |
26 |
27 | EXECUTE
28 | TOOL_CALL_ID
29 | E
30 | LLM Model Tool Call ID
31 |
32 |
33 | GET_TOOL_DETAILS
34 | RESULT
35 | E
36 | Tool details
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/zif_llm_tool_parser.intf.abap:
--------------------------------------------------------------------------------
1 | "!