feat: Add xAI models support (#14523)

This commit is contained in:
Abdul Rahman 2025-09-16 21:25:11 +05:30 committed by GitHub
parent ba3cbd1676
commit 172cc12a82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 119 additions and 5 deletions

View file

@ -48,7 +48,18 @@
"type": "string",
"description": "AI model to use for this agent",
"default": "auto",
"enum": ["auto", "gpt-4", "gpt-4-turbo", "gpt-3.5-turbo", "claude-3-opus", "claude-3-sonnet", "claude-3-haiku"]
"enum": [
"auto",
"gpt-4o",
"gpt-4o-mini",
"gpt-4-turbo",
"claude-opus-4-20250514",
"claude-sonnet-4-20250514",
"claude-3-5-haiku-20241022",
"grok-3",
"grok-3-mini",
"grok-4"
]
},
"responseFormat": {
"type": "object",

View file

@ -1419,7 +1419,8 @@ export enum ModelProvider {
ANTHROPIC = 'ANTHROPIC',
NONE = 'NONE',
OPENAI = 'OPENAI',
OPENAI_COMPATIBLE = 'OPENAI_COMPATIBLE'
OPENAI_COMPATIBLE = 'OPENAI_COMPATIBLE',
XAI = 'XAI'
}
export type Mutation = {

View file

@ -1376,7 +1376,8 @@ export enum ModelProvider {
ANTHROPIC = 'ANTHROPIC',
NONE = 'NONE',
OPENAI = 'OPENAI',
OPENAI_COMPATIBLE = 'OPENAI_COMPATIBLE'
OPENAI_COMPATIBLE = 'OPENAI_COMPATIBLE',
XAI = 'XAI'
}
export type Mutation = {

View file

@ -17,6 +17,7 @@
"dependencies": {
"@ai-sdk/anthropic": "^1.2.12",
"@ai-sdk/openai": "^1.3.22",
"@ai-sdk/xai": "1.2.15",
"@aws-sdk/client-lambda": "3.825.0",
"@aws-sdk/client-s3": "3.825.0",
"@aws-sdk/client-sts": "3.825.0",

View file

@ -7,7 +7,7 @@ import { AI_MODELS, ModelProvider } from './ai-models.const';
describe('AI_MODELS', () => {
it('should contain all expected models', () => {
expect(AI_MODELS).toHaveLength(6);
expect(AI_MODELS).toHaveLength(9);
expect(AI_MODELS.map((model) => model.modelId)).toEqual([
'gpt-4o',
'gpt-4o-mini',
@ -15,6 +15,9 @@ describe('AI_MODELS', () => {
'claude-opus-4-20250514',
'claude-sonnet-4-20250514',
'claude-3-5-haiku-20241022',
'grok-3',
'grok-3-mini',
'grok-4',
]);
});
});

View file

@ -3,6 +3,7 @@ export enum ModelProvider {
OPENAI = 'openai',
ANTHROPIC = 'anthropic',
OPENAI_COMPATIBLE = 'open_ai_compatible',
XAI = 'xai',
}
export type ModelId =
@ -13,6 +14,9 @@ export type ModelId =
| 'claude-opus-4-20250514'
| 'claude-sonnet-4-20250514'
| 'claude-3-5-haiku-20241022'
| 'grok-3'
| 'grok-3-mini'
| 'grok-4'
| string; // Allow custom model names
export interface AIModelConfig {
@ -66,4 +70,25 @@ export const AI_MODELS: AIModelConfig[] = [
inputCostPer1kTokensInCents: 0.08,
outputCostPer1kTokensInCents: 0.4,
},
{
modelId: 'grok-3',
label: 'Grok-3',
provider: ModelProvider.XAI,
inputCostPer1kTokensInCents: 0.3,
outputCostPer1kTokensInCents: 1.5,
},
{
modelId: 'grok-3-mini',
label: 'Grok-3 Mini',
provider: ModelProvider.XAI,
inputCostPer1kTokensInCents: 0.03,
outputCostPer1kTokensInCents: 0.05,
},
{
modelId: 'grok-4',
label: 'Grok-4',
provider: ModelProvider.XAI,
inputCostPer1kTokensInCents: 0.5,
outputCostPer1kTokensInCents: 2.5,
},
];

View file

@ -2,12 +2,13 @@ import { Injectable } from '@nestjs/common';
import { anthropic } from '@ai-sdk/anthropic';
import { createOpenAI, openai } from '@ai-sdk/openai';
import { xai } from '@ai-sdk/xai';
import { type LanguageModel } from 'ai';
import {
AI_MODELS,
type AIModelConfig,
ModelProvider,
type AIModelConfig,
} from 'src/engine/core-modules/ai/constants/ai-models.const';
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
@ -40,6 +41,12 @@ export class AiModelRegistryService {
this.registerAnthropicModels();
}
const xaiApiKey = this.twentyConfigService.get('XAI_API_KEY');
if (xaiApiKey) {
this.registerXaiModels();
}
const openaiCompatibleBaseUrl = this.twentyConfigService.get(
'OPENAI_COMPATIBLE_BASE_URL',
);
@ -83,6 +90,20 @@ export class AiModelRegistryService {
});
}
private registerXaiModels(): void {
const xaiModels = AI_MODELS.filter(
(model) => model.provider === ModelProvider.XAI,
);
xaiModels.forEach((modelConfig) => {
this.modelRegistry.set(modelConfig.modelId, {
modelId: modelConfig.modelId,
provider: ModelProvider.XAI,
model: xai(modelConfig.modelId),
});
});
}
private registerOpenAICompatibleModels(
baseUrl: string,
modelNamesString: string,
@ -206,6 +227,9 @@ export class AiModelRegistryService {
case ModelProvider.ANTHROPIC:
apiKey = this.twentyConfigService.get('ANTHROPIC_API_KEY');
break;
case ModelProvider.XAI:
apiKey = this.twentyConfigService.get('XAI_API_KEY');
break;
case ModelProvider.OPENAI_COMPATIBLE:
apiKey = this.twentyConfigService.get('OPENAI_COMPATIBLE_API_KEY');
break;

View file

@ -1053,6 +1053,15 @@ export class ConfigVariables {
@IsOptional()
OPENAI_COMPATIBLE_API_KEY: string;
@ConfigVariablesMetadata({
group: ConfigVariablesGroup.LLM,
isSensitive: true,
description: 'API key for xAI integration',
type: ConfigVariableType.STRING,
})
@IsOptional()
XAI_API_KEY: string;
@ConfigVariablesMetadata({
group: ConfigVariablesGroup.ServerConfig,
description: 'Enable or disable multi-workspace support',

View file

@ -36,6 +36,18 @@ __metadata:
languageName: node
linkType: hard
"@ai-sdk/openai-compatible@npm:0.2.13":
version: 0.2.13
resolution: "@ai-sdk/openai-compatible@npm:0.2.13"
dependencies:
"@ai-sdk/provider": "npm:1.1.3"
"@ai-sdk/provider-utils": "npm:2.2.7"
peerDependencies:
zod: ^3.0.0
checksum: 10c0/d06d46c319f5b846339aa3ba6144e27791fba4eaa7ba47a758cec52b0c9e578fae61a2ab5cc1f52adaf010a36b3c9309ef46c8ba5de77bea01d15d2d4eb7c27a
languageName: node
linkType: hard
"@ai-sdk/openai@npm:^1.3.22":
version: 1.3.22
resolution: "@ai-sdk/openai@npm:1.3.22"
@ -48,6 +60,19 @@ __metadata:
languageName: node
linkType: hard
"@ai-sdk/provider-utils@npm:2.2.7":
version: 2.2.7
resolution: "@ai-sdk/provider-utils@npm:2.2.7"
dependencies:
"@ai-sdk/provider": "npm:1.1.3"
nanoid: "npm:^3.3.8"
secure-json-parse: "npm:^2.7.0"
peerDependencies:
zod: ^3.23.8
checksum: 10c0/e89a4e03be59df56bfb15e25e761955ffabd39b350527dd3e27da89c35332d1db6eeffc596d2aa3e18a2f5535d79e8ddc4ad7066d6f05f490f7d10082f427f00
languageName: node
linkType: hard
"@ai-sdk/provider-utils@npm:2.2.8":
version: 2.2.8
resolution: "@ai-sdk/provider-utils@npm:2.2.8"
@ -101,6 +126,19 @@ __metadata:
languageName: node
linkType: hard
"@ai-sdk/xai@npm:1.2.15":
version: 1.2.15
resolution: "@ai-sdk/xai@npm:1.2.15"
dependencies:
"@ai-sdk/openai-compatible": "npm:0.2.13"
"@ai-sdk/provider": "npm:1.1.3"
"@ai-sdk/provider-utils": "npm:2.2.7"
peerDependencies:
zod: ^3.0.0
checksum: 10c0/60bd4af83dd90e4b6b3a4149633c77bcfb11e976013f86fd3383f8f23f5fb3afa1d790607fefc34d6a33cfd80fd9680b5b01366a6016070792ab8055b204a55c
languageName: node
linkType: hard
"@algolia/autocomplete-core@npm:1.9.3":
version: 1.9.3
resolution: "@algolia/autocomplete-core@npm:1.9.3"
@ -51712,6 +51750,7 @@ __metadata:
dependencies:
"@ai-sdk/anthropic": "npm:^1.2.12"
"@ai-sdk/openai": "npm:^1.3.22"
"@ai-sdk/xai": "npm:1.2.15"
"@aws-sdk/client-lambda": "npm:3.825.0"
"@aws-sdk/client-s3": "npm:3.825.0"
"@aws-sdk/client-sts": "npm:3.825.0"