diff --git a/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-execution/constants/workflow-agent-excluded-tool-names.const.ts b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-execution/constants/workflow-agent-excluded-tool-names.const.ts new file mode 100644 index 0000000000..db8dc6154c --- /dev/null +++ b/packages/twenty-server/src/engine/metadata-modules/ai/ai-agent-execution/constants/workflow-agent-excluded-tool-names.const.ts @@ -0,0 +1,6 @@ +import { type ActionToolId } from 'src/engine/core-modules/tool-provider/constants/action-tool-label.constant'; + +export const WORKFLOW_AGENT_EXCLUDED_TOOL_NAMES = [ + 'search_help_center', + 'navigate_app', +] as const satisfies readonly ActionToolId[]; diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/__tests__/workflow-version-step-operations.workspace-service.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/__tests__/workflow-version-step-operations.workspace-service.spec.ts index ecd3940a6e..e49ad60f00 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/__tests__/workflow-version-step-operations.workspace-service.spec.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/__tests__/workflow-version-step-operations.workspace-service.spec.ts @@ -6,7 +6,9 @@ import { SEED_WORKFLOW_ACTION_TRIGGER_SETTINGS } from 'twenty-shared/logic-funct import { AiAgentRoleService } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.service'; import { AgentService } from 'src/engine/metadata-modules/ai/ai-agent/agent.service'; +import { AiModelRegistryService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service'; import { WorkflowVersionCoreSyncService } from 'src/engine/core-modules/workflow/services/workflow-version-core-sync.service'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { createEmptyAllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; import { LogicFunctionRuntime } from 'src/engine/metadata-modules/logic-function/logic-function.entity'; @@ -34,6 +36,8 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => { let workflowCommonWorkspaceService: jest.Mocked; let aiAgentRoleService: jest.Mocked; let workspaceCacheService: jest.Mocked; + let aiModelRegistryService: jest.Mocked; + let workspaceRepository: jest.Mocked; beforeEach(async () => { codeStepBuildService = { @@ -123,6 +127,15 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => { flush: jest.fn(), } as unknown as jest.Mocked; + aiModelRegistryService = { + getEffectiveModelConfig: jest.fn(), + validateModelAvailability: jest.fn(), + } as unknown as jest.Mocked; + + workspaceRepository = { + findOneBy: jest.fn().mockResolvedValue(null), + }; + const module: TestingModule = await Test.createTestingModule({ providers: [ WorkflowVersionStepOperationsWorkspaceService, @@ -150,6 +163,14 @@ describe('WorkflowVersionStepOperationsWorkspaceService', () => { provide: getRepositoryToken(ObjectMetadataEntity), useValue: objectMetadataRepository, }, + { + provide: getRepositoryToken(WorkspaceEntity), + useValue: workspaceRepository, + }, + { + provide: AiModelRegistryService, + useValue: aiModelRegistryService, + }, { provide: WorkflowCommonWorkspaceService, useValue: workflowCommonWorkspaceService, diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service.ts index ceec1313b7..96dec4bb57 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-operations.workspace-service.ts @@ -10,9 +10,9 @@ import { import { isDefined, isValidUuid } from 'twenty-shared/utils'; import { IF_ELSE_BRANCH_POSITION_OFFSETS, + WorkflowActionType, getFunctionInputFromInputSchema, type StepIfElseBranch, - WorkflowActionType, } from 'twenty-shared/workflow'; import { Repository } from 'typeorm'; import { v4 } from 'uuid'; @@ -20,14 +20,16 @@ import { v4 } from 'uuid'; import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util'; import { type WorkflowStepPositionInput } from 'src/engine/core-modules/workflow/dtos/update-workflow-step-position.input'; import { WorkflowVersionCoreSyncService } from 'src/engine/core-modules/workflow/services/workflow-version-core-sync.service'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AiAgentRoleService } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.service'; import { AgentService } from 'src/engine/metadata-modules/ai/ai-agent/agent.service'; +import { AiModelRegistryService } from 'src/engine/metadata-modules/ai/ai-models/services/ai-model-registry.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; -import { LogicFunctionFromSourceService } from 'src/engine/metadata-modules/logic-function/services/logic-function-from-source.service'; import { LogicFunctionException, LogicFunctionExceptionCode, } from 'src/engine/metadata-modules/logic-function/logic-function.exception'; +import { LogicFunctionFromSourceService } from 'src/engine/metadata-modules/logic-function/services/logic-function-from-source.service'; import { findFlatLogicFunctionOrThrow } from 'src/engine/metadata-modules/logic-function/utils/find-flat-logic-function-or-throw.util'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity'; @@ -50,7 +52,6 @@ import { type WorkflowEmptyAction, type WorkflowFormAction, } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type'; -import { AUTO_SELECT_SMART_MODEL_ID } from 'twenty-shared/constants'; const BASE_STEP_DEFINITION: BaseWorkflowActionSettings = { outputSchema: {}, errorHandlingOptions: { @@ -77,10 +78,13 @@ export class WorkflowVersionStepOperationsWorkspaceService { private readonly logicFunctionFromSourceService: LogicFunctionFromSourceService, private readonly codeStepBuildService: CodeStepBuildService, private readonly agentService: AgentService, + private readonly aiModelRegistryService: AiModelRegistryService, @InjectWorkspaceScopedRepository(RoleTargetEntity) private readonly roleTargetRepository: WorkspaceScopedRepository, @InjectRepository(ObjectMetadataEntity) private readonly objectMetadataRepository: Repository, + @InjectRepository(WorkspaceEntity) + private readonly workspaceRepository: Repository, private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService, private readonly aiAgentRoleService: AiAgentRoleService, private readonly workspaceCacheService: WorkspaceCacheService, @@ -88,6 +92,26 @@ export class WorkflowVersionStepOperationsWorkspaceService { private readonly workflowVersionCoreSyncService: WorkflowVersionCoreSyncService, ) {} + private async getWorkspaceDefaultFastModelId( + workspaceId: string, + ): Promise { + const workspace = await this.workspaceRepository.findOneBy({ + id: workspaceId, + }); + + if (!isDefined(workspace)) { + throw new WorkflowVersionStepException( + `Workspace ${workspaceId} not found`, + WorkflowVersionStepExceptionCode.NOT_FOUND, + ); + } + + const effectiveModelConfig = + this.aiModelRegistryService.getEffectiveModelConfig(workspace.fastModel); + + return effectiveModelConfig.modelId; + } + async runWorkflowVersionStepDeletionSideEffects({ step, workspaceId, @@ -547,7 +571,7 @@ export class WorkflowVersionStepOperationsWorkspaceService { description: '', prompt: 'You are a helpful AI assistant. Complete the task based on the workflow context.', - modelId: AUTO_SELECT_SMART_MODEL_ID, + modelId: await this.getWorkspaceDefaultFastModelId(workspaceId), responseFormat: { type: 'text' }, isCustom: true, }, diff --git a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.module.ts b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.module.ts index ccf425079b..a3115d69d3 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.module.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.module.ts @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { WorkflowVersionCoreModule } from 'src/engine/core-modules/workflow/workflow-version-core.module'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AiAgentRoleModule } from 'src/engine/metadata-modules/ai/ai-agent-role/ai-agent-role.module'; import { AiAgentModule } from 'src/engine/metadata-modules/ai/ai-agent/ai-agent.module'; import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; @@ -29,7 +30,11 @@ import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workfl AiAgentRoleModule, AiAgentModule, WorkspaceCacheModule, - TypeOrmModule.forFeature([ObjectMetadataEntity, RoleTargetEntity]), + TypeOrmModule.forFeature([ + ObjectMetadataEntity, + RoleTargetEntity, + WorkspaceEntity, + ]), WorkspaceManyOrAllFlatEntityMapsCacheModule, WorkflowVersionCoreModule, ],