[AI] new model tab design (#19384)
closes https://discord.com/channels/1130383047699738754/1480979892610007121 <img width="1839" height="1316" alt="CleanShot 2026-04-07 at 15 22 38" src="https://github.com/user-attachments/assets/d8f6048c-4e0f-425f-b7ea-4913d116020e" />
This commit is contained in:
@@ -228,6 +228,17 @@ export class AdminPanelResolver {
|
||||
return true;
|
||||
}
|
||||
|
||||
@UseGuards(AdminPanelGuard)
|
||||
@Mutation(() => Boolean)
|
||||
async setAdminAiModelsEnabled(
|
||||
@Args('modelIds', { type: () => [String] }) modelIds: string[],
|
||||
@Args('enabled', { type: () => Boolean }) enabled: boolean,
|
||||
): Promise<boolean> {
|
||||
await this.aiModelRegistryService.setModelsAdminEnabled(modelIds, enabled);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@UseGuards(AdminPanelGuard)
|
||||
@Mutation(() => Boolean)
|
||||
async setAdminAiModelRecommended(
|
||||
@@ -239,6 +250,20 @@ export class AdminPanelResolver {
|
||||
return true;
|
||||
}
|
||||
|
||||
@UseGuards(AdminPanelGuard)
|
||||
@Mutation(() => Boolean)
|
||||
async setAdminAiModelsRecommended(
|
||||
@Args('modelIds', { type: () => [String] }) modelIds: string[],
|
||||
@Args('recommended', { type: () => Boolean }) recommended: boolean,
|
||||
): Promise<boolean> {
|
||||
await this.aiModelRegistryService.setModelsRecommended(
|
||||
modelIds,
|
||||
recommended,
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@UseGuards(AdminPanelGuard)
|
||||
@Mutation(() => Boolean)
|
||||
async setAdminDefaultAiModel(
|
||||
|
||||
+13
-4
@@ -56,11 +56,11 @@ export class ClientAIModelConfig {
|
||||
@Field(() => String, { nullable: true })
|
||||
sdkPackage: AiSdkPackage | null;
|
||||
|
||||
@Field(() => Number)
|
||||
inputCostPerMillionTokensInCredits: number;
|
||||
@Field(() => Number, { nullable: true })
|
||||
inputCostPerMillionTokens?: number;
|
||||
|
||||
@Field(() => Number)
|
||||
outputCostPerMillionTokensInCredits: number;
|
||||
@Field(() => Number, { nullable: true })
|
||||
outputCostPerMillionTokens?: number;
|
||||
|
||||
@Field(() => NativeModelCapabilities, { nullable: true })
|
||||
nativeCapabilities?: NativeModelCapabilities;
|
||||
@@ -74,6 +74,15 @@ export class ClientAIModelConfig {
|
||||
@Field(() => String, { nullable: true })
|
||||
providerName?: string;
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
providerLabel?: string;
|
||||
|
||||
@Field(() => Number, { nullable: true })
|
||||
contextWindowTokens?: number;
|
||||
|
||||
@Field(() => Number, { nullable: true })
|
||||
maxOutputTokens?: number;
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
dataResidency?: string;
|
||||
}
|
||||
|
||||
+3
@@ -38,6 +38,9 @@ describe('ClientConfigService', () => {
|
||||
getAdminFilteredModels: jest.fn().mockReturnValue([]),
|
||||
getRecommendedModelIds: jest.fn().mockReturnValue(new Set()),
|
||||
getModelConfig: jest.fn().mockReturnValue(undefined),
|
||||
getResolvedProvidersForAdmin: jest.fn().mockReturnValue({}),
|
||||
getDefaultSpeedModel: jest.fn().mockReturnValue(undefined),
|
||||
getDefaultPerformanceModel: jest.fn().mockReturnValue(undefined),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
+31
-16
@@ -21,7 +21,6 @@ import {
|
||||
import { DomainServerConfigService } from 'src/engine/core-modules/domain/domain-server-config/services/domain-server-config.service';
|
||||
import { PUBLIC_FEATURE_FLAGS } from 'src/engine/core-modules/feature-flag/constants/public-feature-flag.const';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { convertDollarsToBillingCredits } from 'src/engine/metadata-modules/ai/ai-billing/utils/convert-dollars-to-billing-credits.util';
|
||||
import {
|
||||
AUTO_SELECT_FAST_MODEL_ID,
|
||||
AUTO_SELECT_SMART_MODEL_ID,
|
||||
@@ -69,6 +68,13 @@ export class ClientConfigService {
|
||||
this.aiModelRegistryService.getAdminFilteredModels();
|
||||
const recommendedModelIds =
|
||||
this.aiModelRegistryService.getRecommendedModelIds();
|
||||
const resolvedProviders =
|
||||
this.aiModelRegistryService.getResolvedProvidersForAdmin();
|
||||
|
||||
const getProviderLabel = (providerName?: string | null) =>
|
||||
providerName
|
||||
? (resolvedProviders[providerName]?.label ?? providerName)
|
||||
: undefined;
|
||||
|
||||
const aiModels: ClientAIModelConfig[] = availableModels.map(
|
||||
(registeredModel) => {
|
||||
@@ -77,6 +83,7 @@ export class ClientConfigService {
|
||||
);
|
||||
|
||||
const modelFamily = modelConfig?.modelFamily;
|
||||
const providerName = registeredModel.providerName;
|
||||
|
||||
return {
|
||||
modelId: registeredModel.modelId,
|
||||
@@ -86,20 +93,15 @@ export class ClientConfigService {
|
||||
? MODEL_FAMILY_LABELS[modelFamily]
|
||||
: undefined,
|
||||
sdkPackage: registeredModel.sdkPackage,
|
||||
providerName: registeredModel.providerName,
|
||||
providerName,
|
||||
providerLabel: getProviderLabel(providerName),
|
||||
nativeCapabilities: this.deriveNativeCapabilities(
|
||||
registeredModel.sdkPackage,
|
||||
),
|
||||
inputCostPerMillionTokensInCredits: modelConfig
|
||||
? convertDollarsToBillingCredits(
|
||||
modelConfig.inputCostPerMillionTokens,
|
||||
)
|
||||
: 0,
|
||||
outputCostPerMillionTokensInCredits: modelConfig
|
||||
? convertDollarsToBillingCredits(
|
||||
modelConfig.outputCostPerMillionTokens,
|
||||
)
|
||||
: 0,
|
||||
inputCostPerMillionTokens: modelConfig?.inputCostPerMillionTokens,
|
||||
outputCostPerMillionTokens: modelConfig?.outputCostPerMillionTokens,
|
||||
contextWindowTokens: modelConfig?.contextWindowTokens,
|
||||
maxOutputTokens: modelConfig?.maxOutputTokens,
|
||||
isDeprecated: modelConfig?.isDeprecated,
|
||||
isRecommended: recommendedModelIds.has(registeredModel.modelId),
|
||||
dataResidency: modelConfig?.dataResidency,
|
||||
@@ -129,9 +131,17 @@ export class ClientConfigService {
|
||||
'Default',
|
||||
modelFamily: defaultPerformanceModelConfig?.modelFamily,
|
||||
providerName: defaultPerformanceModel?.providerName,
|
||||
providerLabel: getProviderLabel(
|
||||
defaultPerformanceModel?.providerName,
|
||||
),
|
||||
sdkPackage: defaultPerformanceModel?.sdkPackage ?? null,
|
||||
inputCostPerMillionTokensInCredits: 0,
|
||||
outputCostPerMillionTokensInCredits: 0,
|
||||
inputCostPerMillionTokens:
|
||||
defaultPerformanceModelConfig?.inputCostPerMillionTokens,
|
||||
outputCostPerMillionTokens:
|
||||
defaultPerformanceModelConfig?.outputCostPerMillionTokens,
|
||||
contextWindowTokens:
|
||||
defaultPerformanceModelConfig?.contextWindowTokens,
|
||||
maxOutputTokens: defaultPerformanceModelConfig?.maxOutputTokens,
|
||||
},
|
||||
{
|
||||
modelId: AUTO_SELECT_FAST_MODEL_ID,
|
||||
@@ -141,9 +151,14 @@ export class ClientConfigService {
|
||||
'Default',
|
||||
modelFamily: defaultSpeedModelConfig?.modelFamily,
|
||||
providerName: defaultSpeedModel?.providerName,
|
||||
providerLabel: getProviderLabel(defaultSpeedModel?.providerName),
|
||||
sdkPackage: defaultSpeedModel?.sdkPackage ?? null,
|
||||
inputCostPerMillionTokensInCredits: 0,
|
||||
outputCostPerMillionTokensInCredits: 0,
|
||||
inputCostPerMillionTokens:
|
||||
defaultSpeedModelConfig?.inputCostPerMillionTokens,
|
||||
outputCostPerMillionTokens:
|
||||
defaultSpeedModelConfig?.outputCostPerMillionTokens,
|
||||
contextWindowTokens: defaultSpeedModelConfig?.contextWindowTokens,
|
||||
maxOutputTokens: defaultSpeedModelConfig?.maxOutputTokens,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user