diff --git a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/moon.yml b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/moon.yml index c4a73abb028e5..0b3ab7d3f8f48 100644 --- a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/moon.yml +++ b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/moon.yml @@ -34,6 +34,7 @@ dependsOn: - '@kbn/kibana-react-plugin' - '@kbn/cloud-plugin' - '@kbn/deeplinks-management' + - '@kbn/connector-schemas' tags: - shared-browser - package diff --git a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/components/inference_service_form_fields.test.tsx b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/components/inference_service_form_fields.test.tsx index 5db3c41b14ddc..8eef5cc2dcc9a 100644 --- a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/components/inference_service_form_fields.test.tsx +++ b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/components/inference_service_form_fields.test.tsx @@ -18,6 +18,7 @@ import { httpServiceMock } from '@kbn/core-http-browser-mocks'; import { notificationServiceMock } from '@kbn/core-notifications-browser-mocks'; import { mockProviders } from '../utils/mock_providers'; import type { InferenceProvider } from '../types/types'; +import { INTERNAL_OVERRIDE_FIELDS } from '../constants'; // Create a stable cloned copy for each test suite to prevent mutations from affecting other tests // Note: Variable must be prefixed with 'mock' to be allowed in jest.mock() @@ -122,6 +123,19 @@ describe('Inference Services', () => { ); }); + it('populates default model_id when selecting openai provider', async () => { + renderForm(); + + await userEvent.click(screen.getByTestId('provider-select')); + await userEvent.click(screen.getByText('OpenAI')); + + expect(screen.getByTestId('provider-select')).toHaveValue('OpenAI'); + const modelIdInput = screen.getByTestId('model_id-input'); + // Default value comes from INTERNAL_OVERRIDE_FIELDS.openai.defaultValues.model_id + const expectedDefaultModel = INTERNAL_OVERRIDE_FIELDS.openai?.defaultValues?.model_id as string; + expect(modelIdInput).toHaveValue(expectedDefaultModel); + }); + describe('isProviderForSolutions', () => { it('should return true for provider with supported filter type', () => { const provider = { service: 'amazonbedrock', name: 'Amazon Bedrock' } as InferenceProvider; diff --git a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/components/inference_service_form_fields.tsx b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/components/inference_service_form_fields.tsx index 67c13ac211d53..2c99bcef7419b 100644 --- a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/components/inference_service_form_fields.tsx +++ b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/components/inference_service_form_fields.tsx @@ -235,13 +235,11 @@ export const InferenceServiceFormFields: React.FC = ({ const newProvider = updatedProviders?.find( (p) => p.service === (config.provider === '' ? providerSelected : config.provider) ); + const overrides = newProvider ? getOverrides(newProvider) : undefined; + const newProviderSchema: ConfigEntryView[] = newProvider + ? mapProviderFields(taskType, newProvider, overrides) + : []; if (newProvider) { - const overrides = getOverrides(newProvider); - const newProviderSchema: ConfigEntryView[] = mapProviderFields( - taskType, - newProvider, - overrides - ); setProviderSchema(newProviderSchema); } @@ -266,7 +264,9 @@ export const InferenceServiceFormFields: React.FC = ({ newProvider?.configurations[k]?.supported_task_types && newProvider?.configurations[k].supported_task_types.includes(taskType) ) { - newConfig[k] = newProvider?.configurations[k]?.default_value ?? null; + // Get default value from schema (which includes overridden defaults from INTERNAL_OVERRIDE_FIELDS) + const schemaField = newProviderSchema.find((f) => f.key === k); + newConfig[k] = schemaField?.default_value ?? null; } }); @@ -318,11 +318,8 @@ export const InferenceServiceFormFields: React.FC = ({ newProviderSchema.forEach((fieldConfig) => { if (!fieldConfig.sensitive) { - if (fieldConfig && !!fieldConfig.default_value) { - defaultProviderConfig[fieldConfig.key] = fieldConfig.default_value; - } else { - defaultProviderConfig[fieldConfig.key] = null; - } + // default_value now includes overridden defaults from INTERNAL_OVERRIDE_FIELDS + defaultProviderConfig[fieldConfig.key] = fieldConfig.default_value; } else { defaultProviderSecrets[fieldConfig.key] = null; } diff --git a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/constants.tsx b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/constants.tsx index f7cfbd161f1f6..a0e284f66aa3b 100644 --- a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/constants.tsx +++ b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/constants.tsx @@ -7,8 +7,12 @@ import React from 'react'; import { EuiLink } from '@elastic/eui'; +import { DEFAULT_MODEL as BEDROCK_DEFAULT_MODEL } from '@kbn/connector-schemas/bedrock/constants'; +import { DEFAULT_MODEL as GEMINI_DEFAULT_MODEL } from '@kbn/connector-schemas/gemini/constants'; +import { DEFAULT_MODEL as OPENAI_DEFAULT_MODEL } from '@kbn/connector-schemas/openai/constants'; import { GEMINI, DOCUMENTATION_BASE as DOCUMENTATION } from './translations'; -import { FieldType, type InternalOverrideFieldsType } from './types/types'; +import type { InternalOverrideFieldsType } from './types/types'; +import { FieldType } from './types/types'; export enum ServiceProviderKeys { 'alibabacloud-ai-search' = 'alibabacloud-ai-search', @@ -76,6 +80,7 @@ export const MAX_NUMBER_OF_ALLOCATIONS = 'max_number_of_allocations'; export const CONTEXT_WINDOW_LENGTH = 'contextWindowLength'; // This is a temporaray solution to handle the internal overrides for field configurations that have not been updated in the services endpoint +// defaultValues can be used to set default values for model_id fields for providers export const INTERNAL_OVERRIDE_FIELDS: InternalOverrideFieldsType = { [ServiceProviderKeys.elasticsearch]: { hidden: ['num_allocations', 'num_threads'], @@ -96,4 +101,17 @@ export const INTERNAL_OVERRIDE_FIELDS: InternalOverrideFieldsType = { ], serverlessOnly: true, }, + // Default model values for providers + [ServiceProviderKeys.openai]: { + defaultValues: { model_id: OPENAI_DEFAULT_MODEL }, + }, + [ServiceProviderKeys.amazonbedrock]: { + defaultValues: { model: BEDROCK_DEFAULT_MODEL }, + }, + [ServiceProviderKeys.googlevertexai]: { + defaultValues: { model_id: GEMINI_DEFAULT_MODEL }, + }, + [ServiceProviderKeys.googleaistudio]: { + defaultValues: { model_id: GEMINI_DEFAULT_MODEL }, + }, }; diff --git a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/types/dynamic_config/types.ts b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/types/dynamic_config/types.ts index 85eaae3db01e8..d3355b8f3866d 100644 --- a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/types/dynamic_config/types.ts +++ b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/types/dynamic_config/types.ts @@ -63,6 +63,8 @@ export interface OverrideFieldsContentType { serverlessOnly?: boolean; hidden?: string[]; additional?: FieldsConfiguration[]; + /** Default values to apply to existing provider configuration fields (e.g., model_id default values) */ + defaultValues?: Record; } export type InternalOverrideFieldsType = { [Key in ServiceProviderKeysType | string]?: OverrideFieldsContentType; diff --git a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/utils/helpers.ts b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/utils/helpers.ts index 77d478bfae74f..e1cc9b641b0f8 100644 --- a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/utils/helpers.ts +++ b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/utils/helpers.ts @@ -102,13 +102,18 @@ export const mapProviderFields = ( (newProvider.configurations[pk].supported_task_types ?? [taskType]).includes(taskType) && (fieldOverrides?.hidden ?? []).indexOf(pk) === -1 ) - .map( - (k): ConfigEntryView => ({ + .map((k): ConfigEntryView => { + // Use override defaultValues if provider config doesn't have a default_value set + const configDefaultValue = newProvider.configurations[k].default_value; + const overrideDefaultValue = fieldOverrides?.defaultValues?.[k]; + const resolvedDefaultValue = configDefaultValue ?? overrideDefaultValue ?? null; + + return { key: k, isValid: true, validationErrors: [], - value: newProvider.configurations[k].default_value ?? null, - default_value: newProvider.configurations[k].default_value ?? null, + value: resolvedDefaultValue, + default_value: resolvedDefaultValue, description: newProvider.configurations[k].description ?? null, label: newProvider.configurations[k].label ?? '', required: newProvider.configurations[k].required ?? false, @@ -116,6 +121,6 @@ export const mapProviderFields = ( updatable: newProvider.configurations[k].updatable ?? false, type: newProvider.configurations[k].type ?? FieldType.STRING, supported_task_types: newProvider.configurations[k].supported_task_types ?? [], - }) - ); + }; + }); }; diff --git a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/utils/mock_providers.ts b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/utils/mock_providers.ts index 06482619df4c3..c0d1e4ebd3fbb 100644 --- a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/utils/mock_providers.ts +++ b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/src/utils/mock_providers.ts @@ -9,6 +9,43 @@ import type { InferenceProvider } from '../types/types'; import { FieldType } from '../types/types'; export const mockProviders: InferenceProvider[] = [ + { + service: 'openai', + name: 'OpenAI', + task_types: ['completion', 'text_embedding'], + configurations: { + api_key: { + default_value: null, + description: `API Key for the provider you're connecting to.`, + label: 'API Key', + required: true, + sensitive: true, + updatable: true, + type: FieldType.STRING, + supported_task_types: ['completion', 'text_embedding'], + }, + model_id: { + default_value: null, + description: 'The name of the model to use for the inference task.', + label: 'Model ID', + required: true, + sensitive: false, + updatable: true, + type: FieldType.STRING, + supported_task_types: ['completion', 'text_embedding'], + }, + 'rate_limit.requests_per_minute': { + default_value: null, + description: 'Minimize the number of rate limit errors.', + label: 'Rate Limit', + required: false, + sensitive: false, + updatable: true, + type: FieldType.INTEGER, + supported_task_types: ['completion', 'text_embedding'], + }, + }, + }, { service: 'hugging_face', name: 'Hugging Face', diff --git a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/tsconfig.json b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/tsconfig.json index 362dca8259cb6..9183581ac319c 100644 --- a/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/tsconfig.json +++ b/x-pack/platform/packages/shared/kbn-inference-endpoint-ui-common/tsconfig.json @@ -32,6 +32,7 @@ "@kbn/search-api-panels", "@kbn/kibana-react-plugin", "@kbn/cloud-plugin", - "@kbn/deeplinks-management" + "@kbn/deeplinks-management", + "@kbn/connector-schemas" ] }