Migrate agent v2 (#16214)
# Introduction Closes https://github.com/twentyhq/core-team-issues/issues/1980 In this PR we migrate the agent from v1 to v2. ## New FlatRoleTargetByAgentIdMaps Derivated the `flatRoleTargetMaps` to be building a `flatRoleTargetByAgentIdMaps` to ease retrieving a roleId to associate to an agent ## Coverage Added strong coverage on both failing and successful CRU agents operations --------- Co-authored-by: Weiko <corentin@twenty.com>
This commit is contained in:
+13
@@ -0,0 +1,13 @@
|
||||
import { type FlatAgent } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type';
|
||||
|
||||
export const FLAT_AGENT_EDITABLE_PROPERTIES = [
|
||||
'name',
|
||||
'label',
|
||||
'icon',
|
||||
'description',
|
||||
'prompt',
|
||||
'modelId',
|
||||
'responseFormat',
|
||||
'modelConfiguration',
|
||||
'evaluationInputs',
|
||||
] as const satisfies (keyof FlatAgent)[];
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
|
||||
import { WorkspaceFlatAgentMapCacheService } from 'src/engine/metadata-modules/flat-agent/services/workspace-flat-agent-map-cache.service';
|
||||
import { WorkspaceFlatRoleTargetByAgentIdService } from 'src/engine/metadata-modules/flat-agent/services/workspace-flat-role-target-by-agent-id.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([AgentEntity, RoleTargetEntity]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
providers: [
|
||||
WorkspaceFlatAgentMapCacheService,
|
||||
WorkspaceFlatRoleTargetByAgentIdService,
|
||||
],
|
||||
exports: [
|
||||
WorkspaceFlatAgentMapCacheService,
|
||||
WorkspaceFlatRoleTargetByAgentIdService,
|
||||
],
|
||||
})
|
||||
export class FlatAgentModule {}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
|
||||
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
|
||||
import { type FlatAgentMaps } from 'src/engine/metadata-modules/flat-agent/types/flat-agent-maps.type';
|
||||
import { transformAgentEntityToFlatAgent } from 'src/engine/metadata-modules/flat-agent/utils/transform-agent-entity-to-flat-agent.util';
|
||||
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration-v2/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceCache('flatAgentMaps')
|
||||
export class WorkspaceFlatAgentMapCacheService extends WorkspaceCacheProvider<FlatAgentMaps> {
|
||||
constructor(
|
||||
@InjectRepository(AgentEntity)
|
||||
private readonly agentRepository: Repository<AgentEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(workspaceId: string): Promise<FlatAgentMaps> {
|
||||
const agents = await this.agentRepository.find({
|
||||
where: { workspaceId },
|
||||
withDeleted: true,
|
||||
});
|
||||
|
||||
const flatAgentMaps = createEmptyFlatEntityMaps();
|
||||
|
||||
for (const agentEntity of agents) {
|
||||
const flatAgent = transformAgentEntityToFlatAgent(agentEntity);
|
||||
|
||||
addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
|
||||
flatEntity: flatAgent,
|
||||
flatEntityMapsToMutate: flatAgentMaps,
|
||||
});
|
||||
}
|
||||
|
||||
return flatAgentMaps;
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { NonNullableRequired } from 'twenty-shared/types';
|
||||
import { IsNull, Not, Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
|
||||
import { FlatRoleTargetByAgentIdMaps } from 'src/engine/metadata-modules/flat-agent/types/flat-role-target-by-agent-id-maps.type';
|
||||
import { fromRoleTargetsEntityToFlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/utils/from-role-target-entity-to-flat-role-target.util';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceCache('flatRoleTargetByAgentIdMaps')
|
||||
export class WorkspaceFlatRoleTargetByAgentIdService extends WorkspaceCacheProvider<FlatRoleTargetByAgentIdMaps> {
|
||||
constructor(
|
||||
@InjectRepository(RoleTargetEntity)
|
||||
private readonly roleTargetRepository: Repository<RoleTargetEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(
|
||||
workspaceId: string,
|
||||
): Promise<FlatRoleTargetByAgentIdMaps> {
|
||||
const roleTargetEntities = await this.roleTargetRepository.find({
|
||||
where: {
|
||||
workspaceId,
|
||||
agentId: Not(IsNull()),
|
||||
},
|
||||
withDeleted: true,
|
||||
});
|
||||
|
||||
const flatRoleTargetByAgentIdMaps: FlatRoleTargetByAgentIdMaps = {};
|
||||
|
||||
for (const roleTargetEntity of roleTargetEntities as Array<
|
||||
Omit<RoleTargetEntity, 'agentId'> &
|
||||
NonNullableRequired<Pick<RoleTargetEntity, 'agentId'>>
|
||||
>) {
|
||||
const flatRoleTarget =
|
||||
fromRoleTargetsEntityToFlatRoleTarget(roleTargetEntity);
|
||||
|
||||
flatRoleTargetByAgentIdMaps[roleTargetEntity.agentId] = flatRoleTarget;
|
||||
}
|
||||
|
||||
return flatRoleTargetByAgentIdMaps;
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { type FlatAgent } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type';
|
||||
|
||||
export type FlatAgentMaps = FlatEntityMaps<FlatAgent>;
|
||||
+3
-1
@@ -11,5 +11,7 @@ export type AgentEntityRelationProperties =
|
||||
|
||||
export type FlatAgent = FlatEntityFrom<
|
||||
AgentEntity,
|
||||
AgentEntityRelationProperties | 'createdAt' | 'updatedAt' | 'deletedAt'
|
||||
AgentEntityRelationProperties
|
||||
>;
|
||||
|
||||
export type FlatAgentWithRoleId = FlatAgent & { roleId: string | null };
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
import { type FlatRoleTarget } from 'src/engine/metadata-modules/flat-role-target/types/flat-role-target.type';
|
||||
|
||||
export type FlatRoleTargetByAgentIdMaps = Partial<
|
||||
Record<string, FlatRoleTarget>
|
||||
>;
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import { type AgentDTO } from 'src/engine/metadata-modules/ai/ai-agent/dtos/agent.dto';
|
||||
import { type FlatAgentWithRoleId } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type';
|
||||
|
||||
export const fromFlatAgentWithRoleIdToAgentDto = ({
|
||||
applicationId,
|
||||
createdAt,
|
||||
description,
|
||||
evaluationInputs,
|
||||
icon,
|
||||
id,
|
||||
isCustom,
|
||||
label,
|
||||
modelConfiguration,
|
||||
modelId,
|
||||
name,
|
||||
prompt,
|
||||
responseFormat,
|
||||
standardId,
|
||||
updatedAt,
|
||||
workspaceId,
|
||||
roleId,
|
||||
}: FlatAgentWithRoleId): AgentDTO => ({
|
||||
createdAt,
|
||||
description: description ?? undefined,
|
||||
evaluationInputs,
|
||||
id,
|
||||
isCustom,
|
||||
label,
|
||||
modelConfiguration: modelConfiguration ?? undefined,
|
||||
modelId,
|
||||
name,
|
||||
prompt,
|
||||
responseFormat,
|
||||
standardId,
|
||||
updatedAt,
|
||||
workspaceId,
|
||||
applicationId: applicationId ?? undefined,
|
||||
icon: icon ?? undefined,
|
||||
roleId: roleId ?? undefined,
|
||||
});
|
||||
+3
@@ -5,6 +5,9 @@ export const transformAgentEntityToFlatAgent = (
|
||||
agentEntity: AgentEntity,
|
||||
): FlatAgent => {
|
||||
return {
|
||||
createdAt: agentEntity.createdAt,
|
||||
deletedAt: agentEntity.deletedAt,
|
||||
updatedAt: agentEntity.updatedAt,
|
||||
id: agentEntity.id,
|
||||
standardId: agentEntity.standardId,
|
||||
name: agentEntity.name,
|
||||
|
||||
+19
-6
@@ -1,22 +1,35 @@
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
|
||||
import { type FlatAgent } from 'src/engine/metadata-modules/flat-agent/types/flat-agent.type';
|
||||
import { type StandardAgentDefinition } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-agents/types/standard-agent-definition.interface';
|
||||
|
||||
export const transformStandardAgentDefinitionToFlatAgent = (
|
||||
standardAgentDefinition: StandardAgentDefinition,
|
||||
workspaceId: string,
|
||||
): FlatAgent => {
|
||||
export const transformStandardAgentDefinitionToFlatAgent = ({
|
||||
standardAgentDefinition,
|
||||
workspaceId,
|
||||
existingAgentEntity,
|
||||
}: {
|
||||
standardAgentDefinition: StandardAgentDefinition;
|
||||
workspaceId: string;
|
||||
existingAgentEntity?: Pick<
|
||||
AgentEntity,
|
||||
'createdAt' | 'deletedAt' | 'updatedAt' | 'id'
|
||||
>;
|
||||
}): FlatAgent => {
|
||||
const {
|
||||
standardRoleId: _standardRoleId,
|
||||
outputStrategy: _outputStrategy,
|
||||
...agentData
|
||||
} = standardAgentDefinition;
|
||||
const createdAt = new Date();
|
||||
|
||||
return {
|
||||
id: existingAgentEntity?.id ?? v4(),
|
||||
createdAt: existingAgentEntity?.createdAt ?? createdAt,
|
||||
updatedAt: existingAgentEntity?.updatedAt ?? createdAt,
|
||||
deletedAt: existingAgentEntity?.deletedAt ?? null,
|
||||
...agentData,
|
||||
id: v4(),
|
||||
workspaceId,
|
||||
universalIdentifier: standardAgentDefinition.standardId || v4(),
|
||||
universalIdentifier: standardAgentDefinition.standardId,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user