Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Developing Custom DIAL Applications

## Introduction

Whenever the no-code and low-code DIAL extensibility features such as [Quick Apps](/docs/platform/3.core/7.apps.md#quick-apps), [Code Apps](/docs/platform/3.core/7.apps.md#code-apps) or [Mind Maps](/docs/platform/3.core/7.apps.md#mind-maps) are not sufficient to satisfy the needs of a particular use case, a custom application can be developed in any technology stack and exposed through the DIAL platform. From an end-user perspective, such applications will be accessible through the [DIAL Marketplace](/docs/platform/4.chat/1.marketplace.md) similarly to models and standard platform applications.

There are two forms of custom applications in DIAL:

- [Custom Standalone Application](/docs/tutorials/1.developers/4.apps-development/7.develop-single-app.md) – exists as a single logical instance in the platform. Settings and access permissions are managed centrally by an administrator. For example, it can be a standalone document summarization tool, where a platform administrator defines summarization options and quotas.
- [Custom Application Runner](/docs/tutorials/1.developers/4.apps-development/8.develop-app-runner.md) – an application factory that allows end-users create individual logical instances each with its own configuration. For example, a custom RAG application runner may allow an end user to configure a personalized RAG agent by connecting it to chosen data sources, such as internal knowledge bases, document repositories, or external APIs, and then share it with other users and groups. An application runner definition includes a configuration schema that enforces data structure persisted for each instance. It is worth noting that Quick Apps, Code Apps and Mind Maps are application runners available in DIAL platform out of the box.

Regardless of the form, a custom DIAL application may consist of three separate components – Backend, Viewer UI and Editor UI. The purpose and necessity of each one is indicated in the table below.

|Component|Custom Standalone Application|Custom Application Runner|
|---------|-----------------------------|-------------------------|
|Backend|Implements the business logic.<br />**Required**|Implements the business logic.<br />**Required**|
|Viewer UI|An alternative end-user UI (is needed when the default chat interface is not sufficient).<br />**Optional**|An alternative end-user UI (is needed when the default chat interface is not sufficient).<br />**Optional**|
|Editor UI|A UI screen for managing application settings from the [DIAL Admin](/docs/tutorials/3.admin/home.md) application.<br />**Optional**|A UI screen for configuring application settings when creating or updating a logical application instance.<br />**Required**|

There are a few typical sets of components to be developed for a custom DIAL application depending on the use case:

- Backend only – when end-users of a Custom Application are supposed to interact with the application through the default chat interface and there are no application settings to be managed by the DIAL administrator.
- Backend and Admin UI – when a Custom Application has some settings to be managed by the DIAL administrator or you are building a Custom Application Runner, while there is no need to have a custom end-user UI.
- Backend, Admin UI, and End-user UI – when a non-standard end-user UI is needed, and the Custom Application has some settings to be managed by the DIAL administrator, or you are building a Custom Application Runner.

Here is an example of a custom Editor UI accessible through the DIAL Admin for a standalone application:

![](../img/overview1.png)

The screenshots below illustrate a typical user flow for an Application Runner, using Mind Maps as an example where both the Viewer and Editor UIs are customized:

1. All Application Runners that the current user has access to, are available in the “Add App” dropdown in the [user’s Workspace](/docs/tutorials/0.user-guide.md#my-workspace).

![](../img/overview2.png)

2. After populating the General Info tab and proceeding to the App Settings, a custom Editor UI will appear.

![](../img/overview3.png)

![](../img/overview4.png)

3. A custom Viewer UI can be seen when a user opens a logical application instance created this way from his DIAL Workspace or Marketplace.

![](../img/overview5.png)

The diagram below shows the most complete logical structure of a Custom Standalone Application:

![](../img/overview6.png)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to limit the width a little? The image is too big


And the following diagram – the most complete structure of a Custom Application Runner:

![](../img/overview7.png)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to limit the width a little? The image is too big


## Backend

A backend service that implements the necessary business logic and exposes either a standard Open AI chat completion endpoint, or a set of custom API endpoints, or both. Can be implemented using any technology stack, but for simple cases, when only a chat completion endpoint needs to be exposed, it is recommended to use [DIAL SDK for Python](https://github.com/epam/ai-dial-sdk).

For Application Runners, this SDK provides an easy way of getting configuration details about the calling instance (see `request_dial_application_properties` method). These properties are usually managed via a custom Editor UI and are validated by DIAL Core against the configuration schema provided for the application runner.

The service doesn’t have to validate tokens, since authorization is handled by DIAL Core, which serves as an API gateway in this scenario. When forwarding a call to a backend endpoint, DIAL Core passes a [per-request key](/docs/platform/3.core/3.per-request-keys.md) in the `“api-key”` header instead of the original authorization header, which can later be used by the backend logic to call DIAL Core back for accessing models or other applications.

## UI

Both UI pieces are developed and hosted as standalone applications, but when registered in the platform, they get embedded as IFRAME into respective DIAL UI applications, providing integrated experience.

There are no limitations on the technology stack, but it is recommended to use the [Next.js solution template](https://github.com/epam/ai-dial/tree/main/dial-samples/common-ui-app), since it already has all necessary boilerplate code including the authentication mechanism.

As shown on the diagram above, each of the custom UI applications is supposed to be hosted on a separate subdomain. In order to issue a JWT token for accessing endpoints exposed by DIAL Core, each custom UI application must have its own client registration with the Identity Provider. Separate client registrations allow for more granular control over permissions and scopes, enabling each application to request only the access it requires, which aligns with the principle of least privilege. This separation also simplifies auditing and monitoring, as it becomes easier to trace and identify which application is responsible for specific API calls or security events.

Communication with the corresponding backend service is always made through DIAL Core. When the backend exposes custom API endpoints, the corresponding [routes](https://github.com/epam/ai-dial-core/blob/development/docs/dynamic-settings/routes.md) must be configured in the DIAL Core configuration to make them reachable for the UI application.

For Editor UI of an Application Runner it is recommended to save instance configuration in the application object – data stored in `application_properties` attribute of an application instance is validated against the schema provided for the corresponding Application Runner, persisted, and then can be read by the backend depending on the calling instance.

## Deployment

There are no limitations of how and where the custom components are deployed, the only requirement is that there must be network connectivity between DIAL Core and the backend service, as well as between UI applications and DIAL Core. Any communication between components is made only through API.
Here are the links to sample configuration guides for different types of applications:

- [Standalone application](/docs/tutorials/1.developers/4.apps-development/7.develop-single-app.md)
- [Application runner](/docs/tutorials/1.developers/4.apps-development/8.develop-app-runner.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# Developing Chat-Based Standalone Custom Applications

## Introduction

The easiest way to develop a custom application for DIAL, is using the [sample project](https://github.com/epam/ai-dial/blob/main/dial-samples/standalone-app-chat-ui/backend/README.md) as a baseline. The instruction below shows how to set up a local DIAL environment as well as register and run the sample project.

Refer to [Develop Custom Applications](/docs/tutorials/1.developers/4.apps-development/6.develop-custom-apps-overview.md) for a high-level information about application runners.

> **Note**: This tutorial uses a Docker-deployed Keycloak instance as the Identity Provider for demonstration purposes. In your organization, you can apply the same configuration principles to your corporate Identity Provider, using the Keycloak setup here as a reference.

## Running Sample Project

1. Clone the project containing all templates and Docker Compose scripts from the [ai-dial GitHub repository](https://github.com/epam/ai-dial).
2. Run the base Docker Compose file.

1. Go to the `/dial-docker-compose-advanced` folder of the ai-dial GitHub project cloned in the previous step.
2. Run the following command to launch a local DIAL environment with all components necessary for custom application development and testing:

```bash
docker compose -f docker-compose-base.yml up
```


3. Create a client in Keycloak for the custom Admin UI:

1. Open http://localhost:8900 and log in using “admin” as username and password. It is recommended to open this and all further “localhost” references in an incognito browser window.
1. Click **Manage realms** in the left panel and select the **dial** realm in the realms list.
1. Click **Clients** in the left panel and click **Create client**.
1. Set **Client ID** and **Name** to “custom-app-admin” and click **Next**.

![](../img/custom-apps1.png)

1. Turn on the **Client authentication** toggle and click **Next**.

![](../img/custom-apps2.png)

1. Set **Root URL** and **Home URL** to `http://localhost:3301` and **Valid redirect URIs** to `http://localhost:3301/*`, then click **Save**.

![](../img/custom-apps3.png)

1. Go to **Client scopes** tab in the client properties page and click **Add client scope**.

![](../img/custom-apps4.png)

1. Select scopes “profile”, “basic” “email”, and “offline_access”, then click **Add** and select **Default**.

![](../img/custom-apps5.png)

4. Update the custom applications Docker Compose file with client secrets

1. Go to the **Credentials** tab for the “custom-app-admin” client properties in Keycloak.
1. Click the **Copy to clipboard** icon next to the Client Secret input field.

![](../img/custom-apps6.png)

1. Paste the copied value to `AUTH_KEYCLOAK_SECRET` variable in the Docker Compose file `/dial-samples/standalone-app-chat-ui/docker-compose.yml` from the cloned GitHub project.

5. Create a new application in DIAL Admin:
1. Open http://localhost:3102 and log in using “dial-admin” as username and “dial” as password.
1. In the **Entities** section in the left panel, open **Applications** and click **Create** in the right upper corner.
1. Set the **ID** to “custom-app” and the **Display Name** to “Custom Application”.
1. Set **Completion endpoint** to `http://host.docker.internal:3302/openai/deployments/custom-app/chat/completions` and click **Create**.

> **Note**: Please note that the “custom-app” section of this URL must be equal to the name passed to a call to “add_chat_completion” method in the underlying DIAL backend application. If you use a different name in your backend, the URL from above must be updated accordingly.

![](../img/custom-apps7.png)

6. Configure new application:

* Set **Editor URL** to `http://localhost:3301`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list is using bullets, while other lists in the instruction use numbers. I would make everything consistent.

* Go to the **Roles** tab and set the **Make available to specific roles** toggle **off**.
* Go to the **App Routes** tab and click **Add**.
* Set **Display Name** to “API” and click **Create**.
* Set **Path** to “/api/v1/.*”, toggle **Rewrite path** on, select GET, POST, and PUT in the Methods field.
* Set **Upstream Endpoint** to `http://host.docker.internal:3302`.
* Select both “Read” and “Write” in the **Permissions** field.

![](../img/custom-apps8.png)

* Go to the **Roles** sub-tab within the **App Route** properties and toggle **Inherit Application Roles** on, then click **Save**.

7. Make changes in the sample UI application code to make it compatible with the custom API exposed by the backend:

1. Open the folder `/dial-samples/common-ui-app` in an IDE.
1. Go to file `/apps/dial-custom-ui-admin/src/app/[lang]/settings/actions.ts`
1. Comment out the original return statements in both functions and uncomment the following lines of code:

```typescipt
return await configApi.getConfig(token); //In getCofing()
return await configApi.setConfig(config, token); //In saveConfig()
```

> **Tip**: This change makes the custom admin application call the custom backend API that is intended for storing application settings for this custom standalone application.

8. Run Docker Compose for the custom application runner with a chat end-user interface:

1. Go to the `/dial-samples/standalone-app-chat-ui` folder of the cloned GitHub project.
1. Run Docker Compose:

```bash
docker compose -f docker-compose.yml up --build
```

9. Configure the application setting in the DIAL Admin:

1. Get back to the DIAL Admin application at http://localhost:3102.
2. Go to **Entities/Applications** and select **Custom Application** in the table.
3. In the **Properties** page for the “Custom Application” switch to the **Parameters** tab.
4. If you see just the “Login” link in the center of the tab – click it and log in with “dial-admin” as a user and “dial” as a password.

> **Tip**: Now you should see a sample custom configuration page with a single input field called “Number”. In this sample application, this property controls how many times your input will be repeated in the end-user chat in response. The configuration page is served by the URL specified in the “Editor URL” property of the application type.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't sound like a tip, it is rather a note


5. Change the default value of 1 with any other integer number (e.g. 5), then click **Save**.
10. Access the newly-created application named “Custom Application” in the DIAL Marketplace:
1. Open http://localhost:3100
1. Log in using “dial” as username and password.
1. Click the **Marketplace** icon from the left panel.

![](../img/custom-apps9.png)

1. Click on the application named “Custom Application” and then – the **Use Application** button. Now you should see a chat interface, where each of your input messages will be repeated as many times in response, as was specified when configuring the application.

![](../img/custom-apps10.png)

11. Check that the configuration can be changed at any time:

1. Get back to the DIAL Admin application at http://localhost:3102
1. Go to **Entities/Applications** and select “Custom Application” in the table.
1. In the **Properties** page for the “Custom Application” switch to the **Parameters** tab.
1. Change the number to any other value and check if it affects the behavior of the end-user custom application (see step 8).

## Developing a Real-World Application

A real-world standalone custom application can be developed using such sample applications as templates.

* For a scenario with the standard chat interface for end-users (like demonstrated in this tutorial), the dial-custom-ui-client project of the common-ui-app sample can be ignored and removed.
* The Settings page from dial-custom-ui-admin can be changed however needed to satisfy the configurability requirements of your target use case.
* The backend for the scenario with the standard chat interface is using [DIAL SDK](https://github.com/epam/ai-dial-sdk) to implement the chat completion endpoint. There you can find more information and examples of how to build custom chat completion backends.
* The purpose of each environment variable used by the custom application is documented in the README.md of the corresponding project:
- [common-ui-app](https://github.com/epam/ai-dial/blob/main/dial-samples/common-ui-app/README.md)
- [standalone-app-chat-ui](https://github.com/epam/ai-dial/blob/main/dial-samples/standalone-app-chat-ui/backend/README.md)
- [app-runner-chat-ui](https://github.com/epam/ai-dial/blob/main/dial-samples/app-runner-chat-ui/backend/README.md)




Loading