diff --git a/ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.html b/ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.html index c730850474..abfe8500b4 100644 --- a/ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.html @@ -55,31 +55,34 @@ -
+
@if (providerFieldsList.includes('personalAccessToken')) { ai-models.personal-access-token - + {{ 'ai-models.personal-access-token-required' | translate }} } @if (providerFieldsList.includes('projectId')) { - + ai-models.project-id - + {{ 'ai-models.project-id-required' | translate }} } @if (providerFieldsList.includes('location')) { - + ai-models.location - + {{ 'ai-models.location-required' | translate }} @@ -98,16 +101,17 @@ } @if (providerFieldsList.includes('endpoint')) { - + ai-models.endpoint - + {{ 'ai-models.endpoint-required' | translate }} } @if (providerFieldsList.includes('serviceVersion')) { - + ai-models.service-version @@ -117,25 +121,28 @@ ai-models.api-key - + {{ 'ai-models.api-key-required' | translate }} } @if (providerFieldsList.includes('region')) { - + ai-models.region - + {{ 'ai-models.region-required' | translate }} } @if (providerFieldsList.includes('accessKeyId')) { - + ai-models.access-key-id - + {{ 'ai-models.access-key-id-required' | translate }} @@ -145,7 +152,8 @@ ai-models.secret-access-key - + {{ 'ai-models.secret-access-key-required' | translate }} @@ -154,11 +162,58 @@ ai-models.baseurl - + {{ 'ai-models.baseurl-required' | translate }} } + @if (provider === aiProvider.OLLAMA) { +
+
+
+ {{ 'ai-models.authentication' | translate }} +
+ + {{ 'ai-models.authentication-type.none' | translate }} + {{ 'ai-models.authentication-type.basic' | translate }} + {{ 'ai-models.authentication-type.token' | translate }} + +
+
+ @if (aiModelForms.get('configuration.providerConfig.auth.type').value === AuthenticationType.BASIC) { + + ai-models.username + + + {{ 'ai-models.username-required' | translate }} + + + + ai-models.password + + + + {{ 'ai-models.password-required' | translate }} + + + } + @if (aiModelForms.get('configuration.providerConfig.auth.type').value === AuthenticationType.TOKEN) { + + ai-models.token + + + + {{ 'ai-models.token-required' | translate }} + + + } +
+
+ }
diff --git a/ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.ts b/ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.ts index 3294c6ac76..9d0d28e627 100644 --- a/ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.ts @@ -30,6 +30,7 @@ import { AiModelMap, AiProvider, AiProviderTranslations, + AuthenticationType, ModelType, ProviderFieldsAllList } from '@shared/models/ai-model.models'; @@ -37,6 +38,7 @@ import { AiModelService } from '@core/http/ai-model.service'; import { CheckConnectivityDialogComponent } from '@home/components/ai-model/check-connectivity-dialog.component'; import { map } from 'rxjs/operators'; import { deepTrim } from '@core/utils'; +import { TranslateService } from '@ngx-translate/core'; export interface AIModelDialogData { AIModel?: AiModel; @@ -62,18 +64,23 @@ export class AIModelDialogComponent extends DialogComponent, protected router: Router, protected dialogRef: MatDialogRef, @Inject(MAT_DIALOG_DATA) public data: AIModelDialogData, private fb: FormBuilder, private aiModelService: AiModelService, + private translate: TranslateService, private dialog: MatDialog) { super(store, router, dialogRef); @@ -89,18 +96,24 @@ export class AIModelDialogComponent extends DialogComponent { + this.getAuthenticationHint(type); + this.aiModelForms.get('configuration.providerConfig.auth.username').disable(); + this.aiModelForms.get('configuration.providerConfig.auth.password').disable(); + this.aiModelForms.get('configuration.providerConfig.auth.token').disable(); + if (type === AuthenticationType.BASIC) { + this.aiModelForms.get('configuration.providerConfig.auth.username').enable(); + this.aiModelForms.get('configuration.providerConfig.auth.password').enable(); + } + if (type === AuthenticationType.TOKEN) { + this.aiModelForms.get('configuration.providerConfig.auth.token').enable(); + } + }); this.updateValidation(this.provider); } @@ -132,6 +161,16 @@ export class AIModelDialogComponent extends DialogComponent { if (AiModelMap.get(provider).providerFieldsList.includes(key)) { @@ -139,7 +178,13 @@ export class AIModelDialogComponent extends DialogComponent, 'label'>, HasTenantId accessKeyId?: string; secretAccessKey?: string; baseUrl?: string; + auth?: { + type: AuthenticationType; + username?: string; + password?: string; + token?: string + } }; modelId: string; temperature?: number; @@ -242,3 +248,8 @@ export interface CheckConnectivityResult { status: string; errorDetails: string; } +export enum AuthenticationType { + NONE = 'NONE', + BASIC = 'BASIC', + TOKEN = 'TOKEN' +} diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index c1acd62c00..d39078f56a 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1169,7 +1169,21 @@ "check-connectivity-failed": "Test request failed", "no-model-matching": "No models matching '{{entity}}' were found.", "model-required": "Model is required.", - "no-model-text": "No models found." + "no-model-text": "No models found.", + "authentication": "Authentication", + "authentication-basic-hint": "Uses standard HTTP Basic authentication. The username and password will be combined, Base64-encoded, and sent in an \"Authorization\" header with each request to the Ollama server.", + "authentication-token-hint": "Uses Bearer token authentication. The provided token will be sent directly in an \"Authorization\" eader with each request to the Ollama server.", + "authentication-type": { + "none": "None", + "basic": "Basic", + "token": "Token" + }, + "username": "Username", + "username-required": "Username is required.", + "password": "Password", + "password-required": "Password is required.", + "token": "Token", + "token-required": "Token is required." }, "confirm-on-exit": { "message": "You have unsaved changes. Are you sure you want to leave this page?",