diff --git a/apps/chat/README.md b/apps/chat/README.md index eef0d26a5..3fa76a5ae 100644 --- a/apps/chat/README.md +++ b/apps/chat/README.md @@ -121,6 +121,7 @@ AI DIAL Chat uses environment variables for configuration. All environment varia | `RECENT_ADDONS_IDS` | No | A list of IDs for recently-used addons | Any string | | | `THEMES_CONFIG_HOST` | No | The host URL for a custom themes configuration.
Can lead to public and private resource.
Refer to [Theme Customization](../../docs/THEME-CUSTOMIZATION.md) to learn more. | Any string | | | `QUICK_APPS_HOST` | No | The host URL for a Quick Apps Completion URLs.
Can lead to public and private resource. more. | Any string | | +| `QUICK_APPS_SCHEMA_ID` | No | `applicationTypeSchemaId` value for QuickApp application type | Any string | | | `QUICK_APPS_MODEL` | No | A model that will be used in Quick Apps | Any string | | | `FOOTER_HTML_MESSAGE` | No | A message that will be displayed in the application's footer.
Specify in HTML format. | Any string | | | `ANNOUNCEMENT_HTML_MESSAGE` | No | A message of the announcement banner.
Specify in HTML format. | Any string | | diff --git a/apps/chat/environment.d.ts b/apps/chat/environment.d.ts index 853d21b1b..85e8eeac6 100644 --- a/apps/chat/environment.d.ts +++ b/apps/chat/environment.d.ts @@ -8,6 +8,7 @@ declare global { QUICK_APPS_HOST?: string; QUICK_APPS_MODEL?: string; + QUICK_APPS_SCHEMA_ID?: string; DIAL_API_VERSION?: string; APP_BASE_PATH?: string; diff --git a/apps/chat/src/components/Common/ApplicationWizard/form.ts b/apps/chat/src/components/Common/ApplicationWizard/form.ts index b7c0fe805..9c3200dfc 100644 --- a/apps/chat/src/components/Common/ApplicationWizard/form.ts +++ b/apps/chat/src/components/Common/ApplicationWizard/form.ts @@ -35,7 +35,10 @@ import { } from '@/src/constants/default-ui-settings'; import { MIME_FORMAT_REGEX } from '@/src/constants/file'; import { DEFAULT_VERSION } from '@/src/constants/public'; -import { DEFAULT_QUICK_APPS_HOST } from '@/src/constants/quick-apps'; +import { + DEFAULT_QUICK_APPS_HOST, + DEFAULT_QUICK_APPS_SCHEMA_ID, +} from '@/src/constants/quick-apps'; import { DynamicField } from '@/src/components/Common/Forms/DynamicFormFields'; @@ -313,11 +316,9 @@ export const getDefaultValues = ({ maxInputAttachments: String(app?.maxInputAttachments ?? ''), completionUrl: app?.completionUrl ?? '', features: safeStringify(app?.features), - instructions: app ? getQuickAppConfig(app).config.instructions : '', - temperature: app - ? getQuickAppConfig(app).config.temperature - : DEFAULT_TEMPERATURE, - toolset: app ? getToolsetStr(getQuickAppConfig(app).config) : '', + instructions: app ? getQuickAppConfig(app).instructions : '', + temperature: app ? getQuickAppConfig(app).temperature : DEFAULT_TEMPERATURE, + toolset: app ? getToolsetStr(getQuickAppConfig(app)) : '', sources: app?.function?.sourceFolder ?? '', endpoints: app?.function?.mapping ? Object.entries(app.function.mapping).map(([key, value]) => ({ @@ -376,12 +377,14 @@ export const getApplicationData = ( : null; } if (type === ApplicationType.QUICK_APP) { - preparedData.description = createQuickAppConfig({ - description: formData.description ?? '', + preparedData.applicationTypeSchemaId = DefaultsService.get( + 'quickAppsSchemaId', + DEFAULT_QUICK_APPS_SCHEMA_ID, + ); + preparedData.applicationProperties = createQuickAppConfig({ config: formData.toolset, instructions: formData.instructions ?? '', temperature: formData.temperature, - name: formData.name.trim(), }); preparedData.completionUrl = constructPath( DefaultsService.get('quickAppsHost', DEFAULT_QUICK_APPS_HOST), diff --git a/apps/chat/src/constants/quick-apps.ts b/apps/chat/src/constants/quick-apps.ts index 95041bcda..ec08e79b3 100644 --- a/apps/chat/src/constants/quick-apps.ts +++ b/apps/chat/src/constants/quick-apps.ts @@ -1,6 +1,7 @@ -export const QUICK_APP_CONFIG_DIVIDER = '>>>>>>>>>>'; - export const DEFAULT_QUICK_APPS_MODEL = 'gpt-4o'; export const DEFAULT_QUICK_APPS_HOST = 'http://quickapps.dial-development.svc.cluster.local'; + +export const DEFAULT_QUICK_APPS_SCHEMA_ID = + 'https://mydial.epam.com/custom_application_schemas/quickapps'; diff --git a/apps/chat/src/store/settings/settings.reducers.ts b/apps/chat/src/store/settings/settings.reducers.ts index 16f8c7c5b..251ec1616 100644 --- a/apps/chat/src/store/settings/settings.reducers.ts +++ b/apps/chat/src/store/settings/settings.reducers.ts @@ -13,6 +13,7 @@ import { FALLBACK_ASSISTANT_SUBMODEL_ID } from '@/src/constants/default-ui-setti import { DEFAULT_QUICK_APPS_HOST, DEFAULT_QUICK_APPS_MODEL, + DEFAULT_QUICK_APPS_SCHEMA_ID, } from '@/src/constants/quick-apps'; import { RootState } from '..'; @@ -45,6 +46,7 @@ export interface SettingsState { codeEditorPythonVersions: string[]; quickAppsHost?: string; quickAppsModel?: string; + quickAppsSchemaId?: string; dialApiHost?: string; defaultSystemPrompt?: string; } @@ -337,6 +339,11 @@ const selectQuickAppsModel = createSelector( (state) => state.quickAppsModel ?? DEFAULT_QUICK_APPS_MODEL, ); +const selectQuickAppsSchemaId = createSelector( + [rootSelector], + (state) => state.quickAppsSchemaId ?? DEFAULT_QUICK_APPS_SCHEMA_ID, +); + const selectDialApiHost = createSelector( [rootSelector], (state) => state.dialApiHost ?? '', @@ -352,6 +359,7 @@ const selectDefaults = createSelector( selectDefaultAssistantSubmodelId, selectQuickAppsHost, selectQuickAppsModel, + selectQuickAppsSchemaId, selectDialApiHost, selectDefaultSystemPrompt, ], @@ -359,6 +367,7 @@ const selectDefaults = createSelector( assistantSubmodelId, quickAppsHost, quickAppsModel, + quickAppsSchemaId, dialApiHost, defaultSystemPrompt, ) => @@ -366,6 +375,7 @@ const selectDefaults = createSelector( assistantSubmodelId, quickAppsHost, quickAppsModel, + quickAppsSchemaId, dialApiHost, defaultSystemPrompt, }) as Defaults, diff --git a/apps/chat/src/types/applications.ts b/apps/chat/src/types/applications.ts index 2944c7e6c..a091e138e 100644 --- a/apps/chat/src/types/applications.ts +++ b/apps/chat/src/types/applications.ts @@ -1,4 +1,5 @@ import { DialAIEntityFeatures, DialAIEntityModel } from './models'; +import { QuickAppConfig } from './quick-apps'; import { Entity } from '@epam/ai-dial-shared'; @@ -39,6 +40,8 @@ export interface ApiApplicationResponseBase { description_keywords?: string[]; endpoint: string; function?: ApiApplicationFunctionType; + application_type_schema_id?: string; + application_properties?: QuickAppConfig | Record; } export interface ApiApplicationResponsePublication @@ -67,6 +70,8 @@ export interface ApiApplicationModelBase { url?: string; reference?: string; description_keywords?: string[]; + applicationTypeSchemaId?: string; + applicationProperties?: QuickAppConfig | Record; } export interface ApiApplicationModelRegular extends ApiApplicationModelBase { @@ -74,6 +79,11 @@ export interface ApiApplicationModelRegular extends ApiApplicationModelBase { function?: never; } +export interface ApiApplicationModelSchema extends ApiApplicationModelBase { + endpoint?: never; + applicationTypeSchemaId: string; +} + export interface ApiApplicationModelFunction extends ApiApplicationModelBase { endpoint?: never; function: Omit; @@ -81,7 +91,8 @@ export interface ApiApplicationModelFunction extends ApiApplicationModelBase { export type ApiApplicationModel = | ApiApplicationModelRegular - | ApiApplicationModelFunction; + | ApiApplicationModelFunction + | ApiApplicationModelSchema; export interface ApplicationInfo extends Entity { version: string; @@ -98,6 +109,7 @@ export interface CustomApplicationModel env?: Record; }; version: string; + applicationProperties?: QuickAppConfig | Record; } export interface ApplicationLogsType { diff --git a/apps/chat/src/types/models.ts b/apps/chat/src/types/models.ts index 91aa5a3ae..898155685 100644 --- a/apps/chat/src/types/models.ts +++ b/apps/chat/src/types/models.ts @@ -49,6 +49,7 @@ export interface CoreAIEntity { function?: { status: ApplicationStatus; }; + application_type_schema_id?: string; } export interface DialAIEntityFeatures { @@ -91,6 +92,7 @@ export interface DialAIEntityModel extends Omit { topics?: string[]; functionStatus?: ApplicationStatus; + applicationTypeSchemaId?: string; } export interface DialAIEntityAddon extends Omit { diff --git a/apps/chat/src/types/quick-apps.ts b/apps/chat/src/types/quick-apps.ts index 1ae5872fe..3c684a695 100644 --- a/apps/chat/src/types/quick-apps.ts +++ b/apps/chat/src/types/quick-apps.ts @@ -1,8 +1,6 @@ export interface QuickAppConfig { - description: string; instructions: string; model: string; - name: string; temperature: number; web_api_toolset: object; } diff --git a/apps/chat/src/utils/app/application.ts b/apps/chat/src/utils/app/application.ts index 8fd4b1a44..ce92cf2f0 100644 --- a/apps/chat/src/utils/app/application.ts +++ b/apps/chat/src/utils/app/application.ts @@ -3,6 +3,8 @@ import { getTopicColors } from '@/src/utils/app/style-helpers'; import { ApiApplicationModel, + ApiApplicationModelBase, + ApiApplicationModelSchema, ApiApplicationResponse, ApplicationInfo, ApplicationStatus, @@ -18,7 +20,7 @@ import { DESCRIPTION_DELIMITER_REGEX } from '@/src/constants/chat'; import { DEFAULT_TEMPERATURE } from '@/src/constants/default-ui-settings'; import { DEFAULT_QUICK_APPS_MODEL, - QUICK_APP_CONFIG_DIVIDER, + DEFAULT_QUICK_APPS_SCHEMA_ID, } from '@/src/constants/quick-apps'; import { ApiUtils, getApplicationApiKey } from '../server/api'; @@ -53,7 +55,7 @@ export const regenerateApplicationId = ( export const convertApplicationToApi = ( applicationData: Omit, ): ApiApplicationModel => { - const commonData = { + const commonData: ApiApplicationModelBase = { display_name: applicationData.name, display_version: applicationData.version, icon_url: ApiUtils.encodeApiUrl(applicationData.iconUrl ?? ''), @@ -61,9 +63,10 @@ export const convertApplicationToApi = ( features: applicationData.features, input_attachment_types: applicationData.inputAttachmentTypes, max_input_attachments: applicationData.maxInputAttachments, - defaults: {}, reference: applicationData.reference || undefined, description_keywords: applicationData.topics, + applicationTypeSchemaId: applicationData.applicationTypeSchemaId, + applicationProperties: applicationData.applicationProperties, }; if (applicationData.function) { @@ -80,6 +83,9 @@ export const convertApplicationToApi = ( }; } + if (commonData.applicationTypeSchemaId) { + return commonData as ApiApplicationModelSchema; + } return { ...commonData, endpoint: applicationData.completionUrl, @@ -113,6 +119,8 @@ export const convertApplicationFromApi = ( completionUrl: application.endpoint ?? '', folderId: getFolderIdFromEntityId(id), topics: application.description_keywords, + applicationTypeSchemaId: application.application_type_schema_id, + applicationProperties: application.application_properties, ...(appFunction && { function: appFunction, functionStatus: appFunction.status, @@ -120,81 +128,43 @@ export const convertApplicationFromApi = ( }; }; -export const isQuickApp = (entity: DialAIEntityModel) => { - const { description } = entity; - - return !!description?.includes(QUICK_APP_CONFIG_DIVIDER); -}; +export const isQuickApp = (entity: DialAIEntityModel) => + entity.applicationTypeSchemaId === DEFAULT_QUICK_APPS_SCHEMA_ID; export const getModelDescription = (entity: DialAIEntityModel) => { - return entity.description - ? entity.description.split(QUICK_APP_CONFIG_DIVIDER)[0] - : ''; + return entity.description ?? ''; }; export const getModelShortDescription = (entity: DialAIEntityModel) => getModelDescription(entity).split(DESCRIPTION_DELIMITER_REGEX)[0]; -export const parseQuickAppDescription = (desc: string) => { - const [description, config] = desc.split(QUICK_APP_CONFIG_DIVIDER); - - return { - description, - config, - }; -}; - -export const getQuickAppConfig = (entity: DialAIEntityModel) => { - const { description, config } = parseQuickAppDescription( - entity.description ?? QUICK_APP_CONFIG_DIVIDER, - ); - - let parsedConfig: QuickAppConfig; - try { - parsedConfig = JSON.parse(config); - } catch { - parsedConfig = { - description: getModelDescription(entity), - instructions: '', - model: DefaultsService.get('quickAppsModel', DEFAULT_QUICK_APPS_MODEL), - name: entity.name, - temperature: DEFAULT_TEMPERATURE, - web_api_toolset: {}, - }; - } - - return { - description, - config: parsedConfig, - }; +export const getQuickAppConfig = ( + entity: CustomApplicationModel, +): QuickAppConfig => { + return (entity.applicationProperties as QuickAppConfig)?.web_api_toolset + ? (entity.applicationProperties as QuickAppConfig) + : { + instructions: '', + model: DefaultsService.get('quickAppsModel', DEFAULT_QUICK_APPS_MODEL), + temperature: DEFAULT_TEMPERATURE, + web_api_toolset: {}, + }; }; export const createQuickAppConfig = ({ - description, instructions, - name, temperature, config, }: { - description: string; instructions: string; - name: string; temperature: number; config: string; -}) => { - const preparedConfig: QuickAppConfig = { - description, - instructions, - name, - temperature, - web_api_toolset: JSON.parse(config ?? '{}'), - model: DefaultsService.get('quickAppsModel', DEFAULT_QUICK_APPS_MODEL), - }; - - return [description.trim(), JSON.stringify(preparedConfig)].join( - QUICK_APP_CONFIG_DIVIDER, - ); -}; +}): QuickAppConfig => ({ + instructions, + temperature, + web_api_toolset: JSON.parse(config ?? '{}'), + model: DefaultsService.get('quickAppsModel', DEFAULT_QUICK_APPS_MODEL), +}); export const topicToOption = (topic: string) => ({ value: topic, diff --git a/apps/chat/src/utils/app/data/defaults-service.ts b/apps/chat/src/utils/app/data/defaults-service.ts index 5eda365de..cbd604983 100644 --- a/apps/chat/src/utils/app/data/defaults-service.ts +++ b/apps/chat/src/utils/app/data/defaults-service.ts @@ -2,6 +2,7 @@ export interface Defaults { assistantSubmodelId: string; quickAppsHost: string; quickAppsModel: string; + quickAppsSchemaId: string; dialApiHost: string; defaultSystemPrompt: string; } diff --git a/apps/chat/src/utils/server/get-common-page-props.ts b/apps/chat/src/utils/server/get-common-page-props.ts index 4bef8fdd7..7ee1751c9 100644 --- a/apps/chat/src/utils/server/get-common-page-props.ts +++ b/apps/chat/src/utils/server/get-common-page-props.ts @@ -22,6 +22,7 @@ import { import { DEFAULT_QUICK_APPS_HOST, DEFAULT_QUICK_APPS_MODEL, + DEFAULT_QUICK_APPS_SCHEMA_ID, } from '@/src/constants/quick-apps'; import { authOptions } from '@/src/pages/api/auth/[...nextauth]'; @@ -142,6 +143,8 @@ export const getCommonPageProps: GetServerSideProps = async ({ ).split(','), quickAppsHost: process.env.QUICK_APPS_HOST || DEFAULT_QUICK_APPS_HOST, quickAppsModel: process.env.QUICK_APPS_MODEL || DEFAULT_QUICK_APPS_MODEL, + quickAppsSchemaId: + process.env.QUICK_APPS_SCHEMA_ID || DEFAULT_QUICK_APPS_SCHEMA_ID, dialApiHost: process.env.DIAL_API_HOST || '', defaultSystemPrompt: process.env.NEXT_PUBLIC_DEFAULT_SYSTEM_PROMPT || '', }; diff --git a/apps/chat/src/utils/server/get-sorted-entities.ts b/apps/chat/src/utils/server/get-sorted-entities.ts index c36d09194..6d0d3b3be 100644 --- a/apps/chat/src/utils/server/get-sorted-entities.ts +++ b/apps/chat/src/utils/server/get-sorted-entities.ts @@ -189,6 +189,7 @@ export const getSortedEntities = async (token: JWT | null) => { ...(entity.function && { functionStatus: entity.function?.status, }), + applicationTypeSchemaId: entity.application_type_schema_id, }); }