UI: Change entity type name

This commit is contained in:
Artem Dzhereleiko 2025-07-09 18:07:02 +03:00
parent 21ffc12378
commit ad7cfb94ac
12 changed files with 46 additions and 52 deletions

View File

@ -32,19 +32,19 @@ export class AiModelService {
) {} ) {}
public saveAiModel(aiModel: AiModel, config?: RequestConfig): Observable<AiModel> { public saveAiModel(aiModel: AiModel, config?: RequestConfig): Observable<AiModel> {
return this.http.post<AiModel>('/api/ai/model/settings', aiModel, defaultHttpOptionsFromConfig(config)); return this.http.post<AiModel>('/api/ai/model', aiModel, defaultHttpOptionsFromConfig(config));
} }
public getAiModels(pageLink: PageLink, config?: RequestConfig): Observable<PageData<AiModel>> { public getAiModels(pageLink: PageLink, config?: RequestConfig): Observable<PageData<AiModel>> {
return this.http.get<PageData<AiModel>>(`/api/ai/model/settings${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config)); return this.http.get<PageData<AiModel>>(`/api/ai/model${pageLink.toQuery()}`, defaultHttpOptionsFromConfig(config));
} }
public getAiModelById(aiModelId: string, config?: RequestConfig): Observable<AiModel> { public getAiModelById(aiModelId: string, config?: RequestConfig): Observable<AiModel> {
return this.http.get<AiModel>(`/api/ai/model/settings/${aiModelId}`, defaultHttpOptionsFromConfig(config)); return this.http.get<AiModel>(`/api/ai/model/${aiModelId}`, defaultHttpOptionsFromConfig(config));
} }
public deleteAiModel(aiModelId: string, config?: RequestConfig) { public deleteAiModel(aiModelId: string, config?: RequestConfig) {
return this.http.delete(`/api/ai/model/settings/${aiModelId}`, defaultHttpOptionsFromConfig(config)); return this.http.delete(`/api/ai/model/${aiModelId}`, defaultHttpOptionsFromConfig(config));
} }
public checkConnectivity(aiModelWithUserMsg: AiModelWithUserMsg, config?: RequestConfig): Observable<CheckConnectivityResult> { public checkConnectivity(aiModelWithUserMsg: AiModelWithUserMsg, config?: RequestConfig): Observable<CheckConnectivityResult> {

View File

@ -185,7 +185,7 @@ export class EntityService {
case EntityType.MOBILE_APP_BUNDLE: case EntityType.MOBILE_APP_BUNDLE:
observable = this.mobileAppService.getMobileAppBundleInfoById(entityId, config); observable = this.mobileAppService.getMobileAppBundleInfoById(entityId, config);
break; break;
case EntityType.AI_MODEL_SETTINGS: case EntityType.AI_MODEL:
observable = this.aiModelService.getAiModelById(entityId, config); observable = this.aiModelService.getAiModelById(entityId, config);
break; break;
} }
@ -490,7 +490,7 @@ export class EntityService {
pageLink.sortOrder.property = 'title'; pageLink.sortOrder.property = 'title';
entitiesObservable = this.mobileAppService.getTenantMobileAppBundleInfos(pageLink, config); entitiesObservable = this.mobileAppService.getTenantMobileAppBundleInfos(pageLink, config);
break; break;
case EntityType.AI_MODEL_SETTINGS: case EntityType.AI_MODEL:
pageLink.sortOrder.property = 'name'; pageLink.sortOrder.property = 'name';
entitiesObservable = this.aiModelService.getAiModels(pageLink, config); entitiesObservable = this.aiModelService.getAiModels(pageLink, config);
break; break;

View File

@ -28,7 +28,7 @@
appearance="outline" appearance="outline"
labelText="ai-models.ai-model" labelText="ai-models.ai-model"
(entityChanged)="onEntityChange($event)" (entityChanged)="onEntityChange($event)"
[entityType]="entityType.AI_MODEL_SETTINGS" [entityType]="entityType.AI_MODEL"
(createNew)="createModelAi('modelSettingsId')" (createNew)="createModelAi('modelSettingsId')"
formControlName="modelSettingsId"> formControlName="modelSettingsId">
</tb-entity-autocomplete> </tb-entity-autocomplete>

View File

@ -46,11 +46,11 @@ export class AiModelsTableConfigResolver {
private dialog: MatDialog private dialog: MatDialog
) { ) {
this.config.selectionEnabled = true; this.config.selectionEnabled = true;
this.config.entityType = EntityType.AI_MODEL_SETTINGS; this.config.entityType = EntityType.AI_MODEL;
this.config.addAsTextButton = true; this.config.addAsTextButton = true;
this.config.detailsPanelEnabled = false; this.config.detailsPanelEnabled = false;
this.config.entityTranslations = entityTypeTranslations.get(EntityType.AI_MODEL_SETTINGS); this.config.entityTranslations = entityTypeTranslations.get(EntityType.AI_MODEL);
this.config.entityResources = entityTypeResources.get(EntityType.AI_MODEL_SETTINGS); this.config.entityResources = entityTypeResources.get(EntityType.AI_MODEL);
this.config.headerComponent = AiModelTableHeaderComponent; this.config.headerComponent = AiModelTableHeaderComponent;
this.config.addDialogStyle = {width: '850px', maxHeight: '100vh'}; this.config.addDialogStyle = {width: '850px', maxHeight: '100vh'};
@ -65,7 +65,7 @@ export class AiModelsTableConfigResolver {
entity => this.translate.instant(AiProviderTranslations.get(entity.configuration.provider)) entity => this.translate.instant(AiProviderTranslations.get(entity.configuration.provider))
), ),
new EntityTableColumn<AiModel>('aiModel', 'ai-models.ai-model', '33%', new EntityTableColumn<AiModel>('aiModel', 'ai-models.ai-model', '33%',
entity => entity.configuration.modelConfig.modelId, () => ({}), false entity => entity.configuration.modelId, () => ({}), false
) )
) )

View File

@ -117,7 +117,7 @@
</div> </div>
</section> </section>
</section> </section>
<section class="tb-form-panel stroked" formGroupName="modelConfig"> <section class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>ai-models.configuration</div> <div class="tb-form-panel-title" translate>ai-models.configuration</div>
<section class="tb-form-panel no-border no-padding"> <section class="tb-form-panel no-border no-padding">
<section class="tb-form-panel outlined no-border no-padding"> <section class="tb-form-panel outlined no-border no-padding">
@ -139,7 +139,7 @@
matTooltipPosition="above" matTooltipPosition="above"
matTooltipClass="tb-error-tooltip" matTooltipClass="tb-error-tooltip"
[matTooltip]="'ai-models.temperature-min' | translate" [matTooltip]="'ai-models.temperature-min' | translate"
*ngIf="aiModelForms.get('configuration').get('modelConfig').get('temperature').hasError('min')" *ngIf="aiModelForms.get('configuration').get('temperature').hasError('min')"
class="tb-error"> class="tb-error">
warning warning
</mat-icon> </mat-icon>
@ -156,8 +156,8 @@
matTooltipPosition="above" matTooltipPosition="above"
matTooltipClass="tb-error-tooltip" matTooltipClass="tb-error-tooltip"
[matTooltip]="'ai-models.top-p-min-max' | translate" [matTooltip]="'ai-models.top-p-min-max' | translate"
*ngIf="aiModelForms.get('configuration').get('modelConfig').get('topP').hasError('min') || *ngIf="aiModelForms.get('configuration').get('topP').hasError('min') ||
aiModelForms.get('configuration').get('modelConfig').get('topP').hasError('max')" aiModelForms.get('configuration').get('topP').hasError('max')"
class="tb-error"> class="tb-error">
warning warning
</mat-icon> </mat-icon>
@ -176,7 +176,7 @@
matTooltipPosition="above" matTooltipPosition="above"
matTooltipClass="tb-error-tooltip" matTooltipClass="tb-error-tooltip"
[matTooltip]="'ai-models.top-k-min' | translate" [matTooltip]="'ai-models.top-k-min' | translate"
*ngIf="aiModelForms.get('configuration').get('modelConfig').get('topK').hasError('min')" *ngIf="aiModelForms.get('configuration').get('topK').hasError('min')"
class="tb-error"> class="tb-error">
warning warning
</mat-icon> </mat-icon>
@ -216,7 +216,7 @@
matTooltipPosition="above" matTooltipPosition="above"
matTooltipClass="tb-error-tooltip" matTooltipClass="tb-error-tooltip"
[matTooltip]="'ai-models.max-output-token-min' | translate" [matTooltip]="'ai-models.max-output-token-min' | translate"
*ngIf="aiModelForms.get('configuration').get('modelConfig').get('maxOutputTokens').hasError('min')" *ngIf="aiModelForms.get('configuration').get('maxOutputTokens').hasError('min')"
class="tb-error"> class="tb-error">
warning warning
</mat-icon> </mat-icon>

View File

@ -91,15 +91,13 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
serviceAccountKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceAccountKey : '', [Validators.required]], serviceAccountKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceAccountKey : '', [Validators.required]],
serviceAccountKeyFileName: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceAccountKeyFileName : '', [Validators.required]], serviceAccountKeyFileName: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceAccountKeyFileName : '', [Validators.required]],
}), }),
modelConfig: this.fb.group({ modelId: [this.data.AIModel ? this.data.AIModel.configuration?.modelId : '', [Validators.required]],
modelId: [this.data.AIModel ? this.data.AIModel.configuration.modelConfig?.modelId : '', [Validators.required]], temperature: [this.data.AIModel ? this.data.AIModel.configuration?.temperature : null, [Validators.min(0)]],
temperature: [this.data.AIModel ? this.data.AIModel.configuration.modelConfig?.temperature : null, [Validators.min(0)]], topP: this.data.AIModel ? this.data.AIModel.configuration?.topP : [null, [Validators.min(0.1), Validators.max(1)]],
topP: this.data.AIModel ? this.data.AIModel.configuration.modelConfig?.topP : [null, [Validators.min(0.1), Validators.max(1)]], topK: [this.data.AIModel ? this.data.AIModel.configuration?.topK : null, [Validators.min(0)]],
topK: [this.data.AIModel ? this.data.AIModel.configuration.modelConfig?.topK : null, [Validators.min(0)]], frequencyPenalty: [this.data.AIModel ? this.data.AIModel.configuration?.frequencyPenalty : null],
frequencyPenalty: [this.data.AIModel ? this.data.AIModel.configuration.modelConfig?.frequencyPenalty : null], presencePenalty: [this.data.AIModel ? this.data.AIModel.configuration?.presencePenalty : null],
presencePenalty: [this.data.AIModel ? this.data.AIModel.configuration.modelConfig?.presencePenalty : null], maxOutputTokens: [this.data.AIModel ? this.data.AIModel.configuration?.maxOutputTokens : null, [Validators.min(1)]]
maxOutputTokens: [this.data.AIModel ? this.data.AIModel.configuration.modelConfig?.maxOutputTokens : null, [Validators.min(1)]]
})
}) })
}); });
@ -107,7 +105,7 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
takeUntilDestroyed() takeUntilDestroyed()
).subscribe((provider: AiProvider) => { ).subscribe((provider: AiProvider) => {
this.provider = provider; this.provider = provider;
this.aiModelForms.get('configuration.modelConfig').reset({}); // this.aiModelForms.get('configuration').reset({});
this.aiModelForms.get('configuration.providerConfig').reset({}); this.aiModelForms.get('configuration.providerConfig').reset({});
this.updateValidation(provider); this.updateValidation(provider);
}) })

View File

@ -54,17 +54,15 @@ export class CheckConnectivityDialogComponent extends DialogComponent<CheckConne
} }
] ]
}, },
chatModel: { chatModelConfig: {
modelType: "CHAT", modelType: "CHAT",
provider: this.data.AIModel.configuration.provider, provider: this.data.AIModel.configuration.provider,
providerConfig: {...this.data.AIModel.configuration.providerConfig}, providerConfig: {...this.data.AIModel.configuration.providerConfig},
modelConfig: { modelId: this.data.AIModel.configuration.modelId,
modelId: this.data.AIModel.configuration.modelConfig.modelId,
maxRetries: 0, maxRetries: 0,
timeoutSeconds: 20 timeoutSeconds: 20
} }
} }
}
this.aiModelService.checkConnectivity(aiModelWithMsg, { this.aiModelService.checkConnectivity(aiModelWithMsg, {
ignoreErrors: true, ignoreErrors: true,
ignoreLoading: true ignoreLoading: true

View File

@ -291,7 +291,7 @@ export class EntityAutocompleteComponent implements ControlValueAccessor, OnInit
this.entityRequiredText = 'notification.notification-recipient-required'; this.entityRequiredText = 'notification.notification-recipient-required';
this.notFoundEntities = 'notification.no-recipients-text'; this.notFoundEntities = 'notification.no-recipients-text';
break; break;
case EntityType.AI_MODEL_SETTINGS: case EntityType.AI_MODEL:
this.entityText = 'ai-models.ai-model'; this.entityText = 'ai-models.ai-model';
this.noEntitiesMatchingText = 'ai-models.no-model-matching'; this.noEntitiesMatchingText = 'ai-models.no-model-matching';
this.entityRequiredText = 'ai-models.model-required'; this.entityRequiredText = 'ai-models.model-required';

View File

@ -32,7 +32,6 @@ export interface AiModel extends Omit<BaseData<AiModelId>, 'label'>, HasTenantId
serviceAccountKey?: string; serviceAccountKey?: string;
serviceAccountKeyFileName?: string serviceAccountKeyFileName?: string
}; };
modelConfig: {
modelId: string; modelId: string;
temperature?: number | null; temperature?: number | null;
topP?: number; topP?: number;
@ -41,7 +40,6 @@ export interface AiModel extends Omit<BaseData<AiModelId>, 'label'>, HasTenantId
presencePenalty?: number; presencePenalty?: number;
maxOutputTokens?: number; maxOutputTokens?: number;
} }
}
} }
export enum AiProvider { export enum AiProvider {
@ -131,7 +129,7 @@ export interface AiModelWithUserMsg {
userMessage: { userMessage: {
contents: Array<{contentType: string; text: string}>; contents: Array<{contentType: string; text: string}>;
} }
chatModel: { chatModelConfig: {
modelType: string; modelType: string;
provider: AiProvider provider: AiProvider
providerConfig: { providerConfig: {
@ -144,11 +142,11 @@ export interface AiModelWithUserMsg {
serviceAccountKey?: string; serviceAccountKey?: string;
serviceAccountKeyFileName?: string serviceAccountKeyFileName?: string
}; };
modelConfig: { // chatModelConfig: {
modelId: string; modelId: string;
maxRetries: number; maxRetries: number;
timeoutSeconds: number; timeoutSeconds: number;
} // }
} }
} }

View File

@ -51,7 +51,7 @@ export enum EntityType {
MOBILE_APP_BUNDLE = 'MOBILE_APP_BUNDLE', MOBILE_APP_BUNDLE = 'MOBILE_APP_BUNDLE',
MOBILE_APP = 'MOBILE_APP', MOBILE_APP = 'MOBILE_APP',
CALCULATED_FIELD = 'CALCULATED_FIELD', CALCULATED_FIELD = 'CALCULATED_FIELD',
AI_MODEL_SETTINGS = 'AI_MODEL_SETTINGS', AI_MODEL = 'AI_MODEL',
} }
export enum AliasEntityType { export enum AliasEntityType {
@ -496,7 +496,7 @@ export const entityTypeTranslations = new Map<EntityType | AliasEntityType, Enti
} }
], ],
[ [
EntityType.AI_MODEL_SETTINGS, EntityType.AI_MODEL,
{ {
type: 'entity.type-ai-model', type: 'entity.type-ai-model',
typePlural: 'entity.type-ai-models', typePlural: 'entity.type-ai-models',
@ -640,7 +640,7 @@ export const entityTypeResources = new Map<EntityType, EntityTypeResource<BaseDa
} }
], ],
[ [
EntityType.AI_MODEL_SETTINGS, EntityType.AI_MODEL,
{ {
helpLinkId: 'aiModels' helpLinkId: 'aiModels'
} }

View File

@ -18,7 +18,7 @@ import { EntityId } from '@shared/models/id/entity-id';
import { EntityType } from '@shared/models/entity-type.models'; import { EntityType } from '@shared/models/entity-type.models';
export class AiModelId implements EntityId { export class AiModelId implements EntityId {
entityType = EntityType.AI_MODEL_SETTINGS; entityType = EntityType.AI_MODEL;
id: string; id: string;
constructor(id: string) { constructor(id: string) {

View File

@ -37,7 +37,7 @@ export const exportableEntityTypes: Array<EntityType> = [
EntityType.NOTIFICATION_TEMPLATE, EntityType.NOTIFICATION_TEMPLATE,
EntityType.NOTIFICATION_TARGET, EntityType.NOTIFICATION_TARGET,
EntityType.NOTIFICATION_RULE, EntityType.NOTIFICATION_RULE,
EntityType.AI_MODEL_SETTINGS, EntityType.AI_MODEL,
]; ];
export const entityTypesWithoutRelatedData = new Set<EntityType | AliasEntityType>([ export const entityTypesWithoutRelatedData = new Set<EntityType | AliasEntityType>([
@ -46,7 +46,7 @@ export const entityTypesWithoutRelatedData = new Set<EntityType | AliasEntityTyp
EntityType.NOTIFICATION_RULE, EntityType.NOTIFICATION_RULE,
EntityType.TB_RESOURCE, EntityType.TB_RESOURCE,
EntityType.OTA_PACKAGE, EntityType.OTA_PACKAGE,
EntityType.AI_MODEL_SETTINGS, EntityType.AI_MODEL,
]); ]);
export interface VersionCreateConfig { export interface VersionCreateConfig {