UI: Add authentication for Ollama model
This commit is contained in:
		
							parent
							
								
									478b26b223
								
							
						
					
					
						commit
						8a6015f04e
					
				@ -55,31 +55,34 @@
 | 
				
			|||||||
              </mat-option>
 | 
					              </mat-option>
 | 
				
			||||||
            </mat-select>
 | 
					            </mat-select>
 | 
				
			||||||
          </mat-form-field>
 | 
					          </mat-form-field>
 | 
				
			||||||
          <div formGroupName="providerConfig" class="tb-form-panel no-border no-padding">
 | 
					          <div formGroupName="providerConfig" class="tb-form-panel no-border no-padding no-gap">
 | 
				
			||||||
            @if (providerFieldsList.includes('personalAccessToken')) {
 | 
					            @if (providerFieldsList.includes('personalAccessToken')) {
 | 
				
			||||||
              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
					              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
                <mat-label translate>ai-models.personal-access-token</mat-label>
 | 
					                <mat-label translate>ai-models.personal-access-token</mat-label>
 | 
				
			||||||
                <input type="password" required matInput formControlName="personalAccessToken" autocomplete="new-password">
 | 
					                <input type="password" required matInput formControlName="personalAccessToken" autocomplete="new-password">
 | 
				
			||||||
                <tb-toggle-password matSuffix></tb-toggle-password>
 | 
					                <tb-toggle-password matSuffix></tb-toggle-password>
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('personalAccessToken').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.personalAccessToken').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.personalAccessToken').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.personal-access-token-required' | translate }}
 | 
					                  {{ 'ai-models.personal-access-token-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            @if (providerFieldsList.includes('projectId')) {
 | 
					            @if (providerFieldsList.includes('projectId')) {
 | 
				
			||||||
              <mat-form-field class="mat-block flex-1" appearance="outline" subscriptSizing="dynamic">
 | 
					              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
                <mat-label translate>ai-models.project-id</mat-label>
 | 
					                <mat-label translate>ai-models.project-id</mat-label>
 | 
				
			||||||
                <input matInput required formControlName="projectId">
 | 
					                <input matInput required formControlName="projectId">
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('projectId').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.projectId').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.projectId').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.project-id-required' | translate }}
 | 
					                  {{ 'ai-models.project-id-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            @if (providerFieldsList.includes('location')) {
 | 
					            @if (providerFieldsList.includes('location')) {
 | 
				
			||||||
              <mat-form-field class="mat-block flex-1" appearance="outline" subscriptSizing="dynamic">
 | 
					              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
                <mat-label translate>ai-models.location</mat-label>
 | 
					                <mat-label translate>ai-models.location</mat-label>
 | 
				
			||||||
                <input matInput required formControlName="location">
 | 
					                <input matInput required formControlName="location">
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('location').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.location').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.location').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.location-required' | translate }}
 | 
					                  {{ 'ai-models.location-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
@ -98,16 +101,17 @@
 | 
				
			|||||||
              </tb-file-input>
 | 
					              </tb-file-input>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            @if (providerFieldsList.includes('endpoint')) {
 | 
					            @if (providerFieldsList.includes('endpoint')) {
 | 
				
			||||||
              <mat-form-field class="mat-block flex-1" appearance="outline" subscriptSizing="dynamic">
 | 
					              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
                <mat-label translate>ai-models.endpoint</mat-label>
 | 
					                <mat-label translate>ai-models.endpoint</mat-label>
 | 
				
			||||||
                <input required matInput formControlName="endpoint">
 | 
					                <input required matInput formControlName="endpoint">
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('endpoint').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.endpoint').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.endpoint').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.endpoint-required' | translate }}
 | 
					                  {{ 'ai-models.endpoint-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            @if (providerFieldsList.includes('serviceVersion')) {
 | 
					            @if (providerFieldsList.includes('serviceVersion')) {
 | 
				
			||||||
              <mat-form-field class="mat-block flex-1" appearance="outline" subscriptSizing="dynamic">
 | 
					              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
                <mat-label translate>ai-models.service-version</mat-label>
 | 
					                <mat-label translate>ai-models.service-version</mat-label>
 | 
				
			||||||
                <input matInput formControlName="serviceVersion">
 | 
					                <input matInput formControlName="serviceVersion">
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
@ -117,25 +121,28 @@
 | 
				
			|||||||
                <mat-label translate>ai-models.api-key</mat-label>
 | 
					                <mat-label translate>ai-models.api-key</mat-label>
 | 
				
			||||||
                <input type="password" required matInput formControlName="apiKey" autocomplete="new-password">
 | 
					                <input type="password" required matInput formControlName="apiKey" autocomplete="new-password">
 | 
				
			||||||
                <tb-toggle-password matSuffix></tb-toggle-password>
 | 
					                <tb-toggle-password matSuffix></tb-toggle-password>
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('apiKey').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.apiKey').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.apiKey').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.api-key-required' | translate }}
 | 
					                  {{ 'ai-models.api-key-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            @if (providerFieldsList.includes('region')) {
 | 
					            @if (providerFieldsList.includes('region')) {
 | 
				
			||||||
              <mat-form-field class="mat-block flex-1" appearance="outline" subscriptSizing="dynamic">
 | 
					              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
                <mat-label translate>ai-models.region</mat-label>
 | 
					                <mat-label translate>ai-models.region</mat-label>
 | 
				
			||||||
                <input required matInput formControlName="region">
 | 
					                <input required matInput formControlName="region">
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('region').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.region').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.region').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.region-required' | translate }}
 | 
					                  {{ 'ai-models.region-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            @if (providerFieldsList.includes('accessKeyId')) {
 | 
					            @if (providerFieldsList.includes('accessKeyId')) {
 | 
				
			||||||
              <mat-form-field class="mat-block flex-1" appearance="outline" subscriptSizing="dynamic">
 | 
					              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
                <mat-label translate>ai-models.access-key-id</mat-label>
 | 
					                <mat-label translate>ai-models.access-key-id</mat-label>
 | 
				
			||||||
                <input required matInput formControlName="accessKeyId">
 | 
					                <input required matInput formControlName="accessKeyId">
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('accessKeyId').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.accessKeyId').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.accessKeyId').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.access-key-id-required' | translate }}
 | 
					                  {{ 'ai-models.access-key-id-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
@ -145,7 +152,8 @@
 | 
				
			|||||||
                <mat-label translate>ai-models.secret-access-key</mat-label>
 | 
					                <mat-label translate>ai-models.secret-access-key</mat-label>
 | 
				
			||||||
                <input type="password" required matInput formControlName="secretAccessKey" autocomplete="new-password">
 | 
					                <input type="password" required matInput formControlName="secretAccessKey" autocomplete="new-password">
 | 
				
			||||||
                <tb-toggle-password matSuffix></tb-toggle-password>
 | 
					                <tb-toggle-password matSuffix></tb-toggle-password>
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('secretAccessKey').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.secretAccessKey').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.secretAccessKey').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.secret-access-key-required' | translate }}
 | 
					                  {{ 'ai-models.secret-access-key-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
@ -154,11 +162,58 @@
 | 
				
			|||||||
              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
					              <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
                <mat-label translate>ai-models.baseurl</mat-label>
 | 
					                <mat-label translate>ai-models.baseurl</mat-label>
 | 
				
			||||||
                <input required matInput formControlName="baseUrl">
 | 
					                <input required matInput formControlName="baseUrl">
 | 
				
			||||||
                <mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('baseUrl').hasError('required')">
 | 
					                <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.baseUrl').hasError('required') ||
 | 
				
			||||||
 | 
					                  aiModelForms.get('configuration.providerConfig.baseUrl').hasError('pattern')">
 | 
				
			||||||
                  {{ 'ai-models.baseurl-required' | translate }}
 | 
					                  {{ 'ai-models.baseurl-required' | translate }}
 | 
				
			||||||
                </mat-error>
 | 
					                </mat-error>
 | 
				
			||||||
              </mat-form-field>
 | 
					              </mat-form-field>
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            @if (provider === aiProvider.OLLAMA) {
 | 
				
			||||||
 | 
					              <div class="tb-form-panel stroked no-gap no-padding-bottom mb-4" formGroupName="auth">
 | 
				
			||||||
 | 
					                <div class="flex flex-row items-center justify-between xs:flex-col xs:items-start xs:gap-3">
 | 
				
			||||||
 | 
					                  <div class="tb-form-panel-title" tb-hint-tooltip-icon="{{ authenticationHint }}">
 | 
				
			||||||
 | 
					                    {{ 'ai-models.authentication' | translate }}
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  <tb-toggle-select formControlName="type">
 | 
				
			||||||
 | 
					                    <tb-toggle-option [value]="AuthenticationType.NONE">{{ 'ai-models.authentication-type.none' | translate }}</tb-toggle-option>
 | 
				
			||||||
 | 
					                    <tb-toggle-option [value]="AuthenticationType.BASIC">{{ 'ai-models.authentication-type.basic' | translate }}</tb-toggle-option>
 | 
				
			||||||
 | 
					                    <tb-toggle-option [value]="AuthenticationType.TOKEN">{{ 'ai-models.authentication-type.token' | translate }}</tb-toggle-option>
 | 
				
			||||||
 | 
					                  </tb-toggle-select>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="tb-form-panel no-padding no-border no-gap padding-top">
 | 
				
			||||||
 | 
					                  @if (aiModelForms.get('configuration.providerConfig.auth.type').value === AuthenticationType.BASIC) {
 | 
				
			||||||
 | 
					                    <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
 | 
					                      <mat-label translate>ai-models.username</mat-label>
 | 
				
			||||||
 | 
					                      <input required matInput formControlName="username">
 | 
				
			||||||
 | 
					                      <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.auth.username').hasError('required') ||
 | 
				
			||||||
 | 
					                        aiModelForms.get('configuration.providerConfig.auth.username').hasError('pattern')">
 | 
				
			||||||
 | 
					                        {{ 'ai-models.username-required' | translate }}
 | 
				
			||||||
 | 
					                      </mat-error>
 | 
				
			||||||
 | 
					                    </mat-form-field>
 | 
				
			||||||
 | 
					                    <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
 | 
					                      <mat-label translate>ai-models.password</mat-label>
 | 
				
			||||||
 | 
					                      <input type="password" required matInput formControlName="password" autocomplete="new-password">
 | 
				
			||||||
 | 
					                      <tb-toggle-password matSuffix></tb-toggle-password>
 | 
				
			||||||
 | 
					                      <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.auth.password').hasError('required') ||
 | 
				
			||||||
 | 
					                        aiModelForms.get('configuration.providerConfig.auth.password').hasError('pattern')">
 | 
				
			||||||
 | 
					                        {{ 'ai-models.password-required' | translate }}
 | 
				
			||||||
 | 
					                      </mat-error>
 | 
				
			||||||
 | 
					                    </mat-form-field>
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                  @if (aiModelForms.get('configuration.providerConfig.auth.type').value === AuthenticationType.TOKEN) {
 | 
				
			||||||
 | 
					                    <mat-form-field class="mat-block flex-1" appearance="outline">
 | 
				
			||||||
 | 
					                      <mat-label translate>ai-models.token</mat-label>
 | 
				
			||||||
 | 
					                      <input type="password" required matInput formControlName="token" autocomplete="new-password">
 | 
				
			||||||
 | 
					                      <tb-toggle-password matSuffix></tb-toggle-password>
 | 
				
			||||||
 | 
					                      <mat-error *ngIf="aiModelForms.get('configuration.providerConfig.auth.token').hasError('required') ||
 | 
				
			||||||
 | 
					                        aiModelForms.get('configuration.providerConfig.auth.token').hasError('pattern')">
 | 
				
			||||||
 | 
					                        {{ 'ai-models.token-required' | translate }}
 | 
				
			||||||
 | 
					                      </mat-error>
 | 
				
			||||||
 | 
					                    </mat-form-field>
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </section>
 | 
					        </section>
 | 
				
			||||||
      </section>
 | 
					      </section>
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,7 @@ import {
 | 
				
			|||||||
  AiModelMap,
 | 
					  AiModelMap,
 | 
				
			||||||
  AiProvider,
 | 
					  AiProvider,
 | 
				
			||||||
  AiProviderTranslations,
 | 
					  AiProviderTranslations,
 | 
				
			||||||
 | 
					  AuthenticationType,
 | 
				
			||||||
  ModelType,
 | 
					  ModelType,
 | 
				
			||||||
  ProviderFieldsAllList
 | 
					  ProviderFieldsAllList
 | 
				
			||||||
} from '@shared/models/ai-model.models';
 | 
					} 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 { CheckConnectivityDialogComponent } from '@home/components/ai-model/check-connectivity-dialog.component';
 | 
				
			||||||
import { map } from 'rxjs/operators';
 | 
					import { map } from 'rxjs/operators';
 | 
				
			||||||
import { deepTrim } from '@core/utils';
 | 
					import { deepTrim } from '@core/utils';
 | 
				
			||||||
 | 
					import { TranslateService } from '@ngx-translate/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface AIModelDialogData {
 | 
					export interface AIModelDialogData {
 | 
				
			||||||
  AIModel?: AiModel;
 | 
					  AIModel?: AiModel;
 | 
				
			||||||
@ -62,18 +64,23 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
 | 
				
			|||||||
  providerMap: AiProvider[] = Object.keys(AiProvider) as AiProvider[];
 | 
					  providerMap: AiProvider[] = Object.keys(AiProvider) as AiProvider[];
 | 
				
			||||||
  providerTranslationMap = AiProviderTranslations;
 | 
					  providerTranslationMap = AiProviderTranslations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  AuthenticationType = AuthenticationType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  provider: AiProvider = AiProvider.OPENAI;
 | 
					  provider: AiProvider = AiProvider.OPENAI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  aiModelForms: FormGroup;
 | 
					  aiModelForms: FormGroup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isAdd = false;
 | 
					  isAdd = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  authenticationHint: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(protected store: Store<AppState>,
 | 
					  constructor(protected store: Store<AppState>,
 | 
				
			||||||
              protected router: Router,
 | 
					              protected router: Router,
 | 
				
			||||||
              protected dialogRef: MatDialogRef<AIModelDialogComponent, AiModel>,
 | 
					              protected dialogRef: MatDialogRef<AIModelDialogComponent, AiModel>,
 | 
				
			||||||
              @Inject(MAT_DIALOG_DATA) public data: AIModelDialogData,
 | 
					              @Inject(MAT_DIALOG_DATA) public data: AIModelDialogData,
 | 
				
			||||||
              private fb: FormBuilder,
 | 
					              private fb: FormBuilder,
 | 
				
			||||||
              private aiModelService: AiModelService,
 | 
					              private aiModelService: AiModelService,
 | 
				
			||||||
 | 
					              private translate: TranslateService,
 | 
				
			||||||
              private dialog: MatDialog) {
 | 
					              private dialog: MatDialog) {
 | 
				
			||||||
    super(store, router, dialogRef);
 | 
					    super(store, router, dialogRef);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,18 +96,24 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
 | 
				
			|||||||
      configuration: this.fb.group({
 | 
					      configuration: this.fb.group({
 | 
				
			||||||
        provider: [this.provider, []],
 | 
					        provider: [this.provider, []],
 | 
				
			||||||
        providerConfig: this.fb.group({
 | 
					        providerConfig: this.fb.group({
 | 
				
			||||||
          apiKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.apiKey : '', [Validators.required]],
 | 
					          apiKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.apiKey : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
          personalAccessToken: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.personalAccessToken : '', [Validators.required]],
 | 
					          personalAccessToken: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.personalAccessToken : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
          endpoint: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.endpoint : '', [Validators.required]],
 | 
					          endpoint: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.endpoint : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
          serviceVersion: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceVersion : ''],
 | 
					          serviceVersion: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceVersion : ''],
 | 
				
			||||||
          projectId: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.projectId : '', [Validators.required]],
 | 
					          projectId: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.projectId : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
          location: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.location : '', [Validators.required]],
 | 
					          location: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.location : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
          serviceAccountKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceAccountKey : '', [Validators.required]],
 | 
					          serviceAccountKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceAccountKey : '', [Validators.required]],
 | 
				
			||||||
          fileName: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.fileName : '', [Validators.required]],
 | 
					          fileName: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.fileName : '', [Validators.required]],
 | 
				
			||||||
          region: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.region : '', [Validators.required]],
 | 
					          region: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.region : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
          accessKeyId: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.accessKeyId : '', [Validators.required]],
 | 
					          accessKeyId: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.accessKeyId : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
          secretAccessKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.secretAccessKey : '', [Validators.required]],
 | 
					          secretAccessKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.secretAccessKey : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
          baseUrl: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.baseUrl : '', [Validators.required]],
 | 
					          baseUrl: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.baseUrl : '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
 | 
					          auth: this.fb.group({
 | 
				
			||||||
 | 
					            type: [this.data.AIModel?.configuration?.providerConfig?.auth?.type ?? AuthenticationType.NONE],
 | 
				
			||||||
 | 
					            username: [this.data.AIModel?.configuration?.providerConfig?.auth?.username ?? '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
 | 
					            password: [this.data.AIModel?.configuration?.providerConfig?.auth?.password ?? '', [Validators.required, Validators.pattern(/.*\S.*/)]],
 | 
				
			||||||
 | 
					            token: [this.data.AIModel?.configuration?.providerConfig?.auth?.token ?? '', [Validators.required, Validators.pattern(/.*\S.*/)]]
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        modelId: [this.data.AIModel ? this.data.AIModel.configuration?.modelId : '', [Validators.required]],
 | 
					        modelId: [this.data.AIModel ? this.data.AIModel.configuration?.modelId : '', [Validators.required]],
 | 
				
			||||||
        temperature: [this.data.AIModel ? this.data.AIModel.configuration?.temperature : null, [Validators.min(0)]],
 | 
					        temperature: [this.data.AIModel ? this.data.AIModel.configuration?.temperature : null, [Validators.min(0)]],
 | 
				
			||||||
@ -120,7 +133,23 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
 | 
				
			|||||||
      this.aiModelForms.get('configuration.modelId').reset('');
 | 
					      this.aiModelForms.get('configuration.modelId').reset('');
 | 
				
			||||||
      this.aiModelForms.get('configuration.providerConfig').reset({});
 | 
					      this.aiModelForms.get('configuration.providerConfig').reset({});
 | 
				
			||||||
      this.updateValidation(provider);
 | 
					      this.updateValidation(provider);
 | 
				
			||||||
    })
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.aiModelForms.get('configuration.providerConfig.auth.type').valueChanges.pipe(
 | 
				
			||||||
 | 
					      takeUntilDestroyed()
 | 
				
			||||||
 | 
					    ).subscribe((type: AuthenticationType) => {
 | 
				
			||||||
 | 
					      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);
 | 
					    this.updateValidation(this.provider);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -132,6 +161,16 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private getAuthenticationHint(type: AuthenticationType) {
 | 
				
			||||||
 | 
					    if (type === AuthenticationType.BASIC) {
 | 
				
			||||||
 | 
					      this.authenticationHint = this.translate.instant('ai-models.authentication-basic-hint');
 | 
				
			||||||
 | 
					    } else if (type === AuthenticationType.TOKEN) {
 | 
				
			||||||
 | 
					      this.authenticationHint = this.translate.instant('ai-models.authentication-token-hint');
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.authenticationHint = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private updateValidation(provider: AiProvider) {
 | 
					  private updateValidation(provider: AiProvider) {
 | 
				
			||||||
    ProviderFieldsAllList.forEach(key => {
 | 
					    ProviderFieldsAllList.forEach(key => {
 | 
				
			||||||
      if (AiModelMap.get(provider).providerFieldsList.includes(key)) {
 | 
					      if (AiModelMap.get(provider).providerFieldsList.includes(key)) {
 | 
				
			||||||
@ -139,7 +178,13 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
 | 
				
			|||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        this.aiModelForms.get('configuration.providerConfig').get(key).disable();
 | 
					        this.aiModelForms.get('configuration.providerConfig').get(key).disable();
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    })
 | 
					    });
 | 
				
			||||||
 | 
					    if (provider === AiProvider.OLLAMA) {
 | 
				
			||||||
 | 
					      this.aiModelForms.get('configuration.providerConfig.auth').enable();
 | 
				
			||||||
 | 
					      this.aiModelForms.get('configuration.providerConfig.auth.type').patchValue(this.data.AIModel?.configuration?.providerConfig?.auth?.type ?? AuthenticationType.NONE, {emitEvent: true});
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.aiModelForms.get('configuration.providerConfig.auth').disable();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get providerFieldsList(): string[] {
 | 
					  get providerFieldsList(): string[] {
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,12 @@ export interface AiModel extends Omit<BaseData<AiModelId>, 'label'>, HasTenantId
 | 
				
			|||||||
      accessKeyId?: string;
 | 
					      accessKeyId?: string;
 | 
				
			||||||
      secretAccessKey?: string;
 | 
					      secretAccessKey?: string;
 | 
				
			||||||
      baseUrl?: string;
 | 
					      baseUrl?: string;
 | 
				
			||||||
 | 
					      auth?: {
 | 
				
			||||||
 | 
					        type: AuthenticationType;
 | 
				
			||||||
 | 
					        username?: string;
 | 
				
			||||||
 | 
					        password?: string;
 | 
				
			||||||
 | 
					        token?: string
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    modelId: string;
 | 
					    modelId: string;
 | 
				
			||||||
    temperature?: number;
 | 
					    temperature?: number;
 | 
				
			||||||
@ -242,3 +248,8 @@ export interface CheckConnectivityResult {
 | 
				
			|||||||
  status: string;
 | 
					  status: string;
 | 
				
			||||||
  errorDetails: string;
 | 
					  errorDetails: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					export enum AuthenticationType {
 | 
				
			||||||
 | 
					  NONE = 'NONE',
 | 
				
			||||||
 | 
					  BASIC = 'BASIC',
 | 
				
			||||||
 | 
					  TOKEN = 'TOKEN'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1169,7 +1169,21 @@
 | 
				
			|||||||
        "check-connectivity-failed": "Test request failed",
 | 
					        "check-connectivity-failed": "Test request failed",
 | 
				
			||||||
        "no-model-matching": "No models matching '{{entity}}' were found.",
 | 
					        "no-model-matching": "No models matching '{{entity}}' were found.",
 | 
				
			||||||
        "model-required": "Model is required.",
 | 
					        "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": {
 | 
					    "confirm-on-exit": {
 | 
				
			||||||
        "message": "You have unsaved changes. Are you sure you want to leave this page?",
 | 
					        "message": "You have unsaved changes. Are you sure you want to leave this page?",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user