Fix ai agent node prompt and variables (#18275)

- prompt stored on workflow lvl so input variables can be resolved and
it can evolves with versions
- make ai agent node output available as variables
This commit is contained in:
Thomas Trompette
2026-02-26 17:17:48 +01:00
committed by GitHub
parent 81698ff32c
commit def5ea5764
6 changed files with 69 additions and 84 deletions
@@ -1,17 +1,11 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
@Module({
imports: [
WorkflowCommonModule,
FeatureFlagModule,
TypeOrmModule.forFeature([AgentEntity]),
],
imports: [WorkflowCommonModule, FeatureFlagModule],
providers: [WorkflowSchemaWorkspaceService],
exports: [WorkflowSchemaWorkspaceService],
})
@@ -1,5 +1,4 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { isString } from '@sniptt/guards';
import { isDefined, isValidVariable } from 'twenty-shared/utils';
@@ -12,11 +11,9 @@ import {
SingleRecordAvailability,
TRIGGER_STEP_ID,
} from 'twenty-shared/workflow';
import { Repository } from 'typeorm';
import { type DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
import { checkStringIsDatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/utils/check-string-is-database-event-action';
import { AgentEntity } from 'src/engine/metadata-modules/ai/ai-agent/entities/agent.entity';
import { generateFakeValue } from 'src/engine/utils/generate-fake-value';
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
import { DEFAULT_ITERATOR_CURRENT_ITEM } from 'src/modules/workflow/workflow-builder/workflow-schema/constants/default-iterator-current-item.const';
@@ -45,8 +42,6 @@ import {
export class WorkflowSchemaWorkspaceService {
constructor(
private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService,
@InjectRepository(AgentEntity)
private readonly agentRepository: Repository<AgentEntity>,
) {}
async computeStepOutputSchema({
@@ -128,37 +123,14 @@ export class WorkflowSchemaWorkspaceService {
};
}
case WorkflowActionType.AI_AGENT: {
const agentId = step.settings.input.agentId;
if (!isDefined(agentId) || agentId === '') {
return {};
}
const agent = await this.agentRepository.findOne({
where: { id: agentId, workspaceId },
});
if (
!isDefined(agent) ||
agent.responseFormat?.type !== 'json' ||
!isDefined(agent.responseFormat.schema)
) {
return {};
}
return Object.fromEntries(
Object.entries(agent.responseFormat.schema.properties).map(
([key, field]) => [
key,
{
isLeaf: true,
type: field.type,
label: field.description || key,
value: null,
},
],
),
) as OutputSchema;
return {
response: {
label: 'Response',
isLeaf: true,
type: 'string',
value: 'Response of the agent',
},
};
}
case WorkflowActionType.CODE: // StepOutput schema is computed on logicFunction draft execution
default:
@@ -175,10 +147,7 @@ export class WorkflowSchemaWorkspaceService {
workspaceId: string;
workflowVersionId: string;
}): Promise<WorkflowAction> {
const BACKEND_ENRICHED_TYPES = [
WorkflowActionType.AI_AGENT,
WorkflowActionType.ITERATOR,
];
const BACKEND_ENRICHED_TYPES = [WorkflowActionType.ITERATOR];
if (!BACKEND_ENRICHED_TYPES.includes(step.type)) {
return step;