Fix SSE for workflow show page (#17582)

- Add SSE to workflow show page. Listens at workflow versions
- Add a tool for creating trigger
- Ensure step id is not used in params
- Make AI adding step linked to the last node by default



https://github.com/user-attachments/assets/41ee1835-9716-450e-82e8-54e1b63bd1ef
This commit is contained in:
Thomas Trompette
2026-01-30 18:22:07 +01:00
committed by GitHub
parent 15b053de46
commit 1fea3f8228
11 changed files with 173 additions and 14 deletions
@@ -8,6 +8,7 @@ import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspac
import { type RolePermissionConfig } from 'src/engine/twenty-orm/types/role-permission-config';
import { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
import { WorkflowVersionEdgeWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-edge/workflow-version-edge.workspace-service';
import { WorkflowVersionStepHelpersWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-helpers.workspace-service';
import { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.workspace-service';
import { WorkflowVersionWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.workspace-service';
import {
@@ -26,6 +27,7 @@ import { createDeleteWorkflowVersionStepTool } from 'src/modules/workflow/workfl
import { createGetWorkflowCurrentVersionTool } from 'src/modules/workflow/workflow-tools/tools/get-workflow-current-version.tool';
import { createUpdateWorkflowVersionPositionsTool } from 'src/modules/workflow/workflow-tools/tools/update-workflow-version-positions.tool';
import { createUpdateWorkflowVersionStepTool } from 'src/modules/workflow/workflow-tools/tools/update-workflow-version-step.tool';
import { createUpdateWorkflowVersionTriggerTool } from 'src/modules/workflow/workflow-tools/tools/update-workflow-version-trigger.tool';
import { type WorkflowToolDependencies } from 'src/modules/workflow/workflow-tools/types/workflow-tool-dependencies.type';
import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service';
@@ -36,6 +38,7 @@ export class WorkflowToolWorkspaceService {
constructor(
workflowVersionStepService: WorkflowVersionStepWorkspaceService,
workflowVersionStepHelpersService: WorkflowVersionStepHelpersWorkspaceService,
workflowVersionEdgeService: WorkflowVersionEdgeWorkspaceService,
workflowVersionService: WorkflowVersionWorkspaceService,
workflowTriggerService: WorkflowTriggerWorkspaceService,
@@ -46,6 +49,7 @@ export class WorkflowToolWorkspaceService {
) {
this.deps = {
workflowVersionStepService,
workflowVersionStepHelpersService,
workflowVersionEdgeService,
workflowVersionService,
workflowTriggerService,
@@ -79,6 +83,10 @@ export class WorkflowToolWorkspaceService {
this.deps,
context,
);
const updateWorkflowVersionTrigger = createUpdateWorkflowVersionTriggerTool(
this.deps,
context,
);
const deleteWorkflowVersionStep = createDeleteWorkflowVersionStepTool(
this.deps,
context,
@@ -116,6 +124,7 @@ export class WorkflowToolWorkspaceService {
[createCompleteWorkflow.name]: createCompleteWorkflow,
[createWorkflowVersionStep.name]: createWorkflowVersionStep,
[updateWorkflowVersionStep.name]: updateWorkflowVersionStep,
[updateWorkflowVersionTrigger.name]: updateWorkflowVersionTrigger,
[deleteWorkflowVersionStep.name]: deleteWorkflowVersionStep,
[createWorkflowVersionEdge.name]: createWorkflowVersionEdge,
[deleteWorkflowVersionEdge.name]: deleteWorkflowVersionEdge,
@@ -82,7 +82,7 @@ export const createCreateCompleteWorkflowTool = (
CRITICAL SCHEMA REQUIREMENTS:
- Trigger type MUST be one of: DATABASE_EVENT, MANUAL, CRON, WEBHOOK
- NEVER use "RECORD_CREATED" - this is invalid. Use "DATABASE_EVENT" instead.
- Each step MUST include: id, name, type, valid, settings
- Each step MUST include: id (must be a valid UUID), name, type, valid, settings
- CREATE_RECORD actions MUST have objectName and objectRecord in settings.input
- objectRecord must contain actual field values, not just field names
- Use "trigger" as stepId for trigger step in stepPositions and edges
@@ -97,7 +97,7 @@ IMPORTANT: The tool schema provides comprehensive field descriptions, examples,
- Field requirements and data types
- Common object patterns and field structures
- Proper relationship field formats
- Variable reference syntax (e.g., {{trigger.object.fieldName}})
- Variable reference syntax: {{trigger.fieldName}} for trigger data, {{<step-id>.result.fieldName}} for step outputs (step-id is the step's UUID, not its name)
- Error handling options
This is the most efficient way for AI to create workflows as it handles all the complexity in one call.`,
@@ -1,3 +1,5 @@
import { isDefined } from 'twenty-shared/utils';
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
import { z } from 'zod';
import type { CreateWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/create-workflow-version-step-input.dto';
@@ -17,7 +19,9 @@ const createWorkflowVersionStepSchema = z.object({
parentStepId: z
.string()
.optional()
.describe('Optional ID of the parent step this step should come after'),
.describe(
'Optional ID of the parent step this step should come after. If not provided, the step will be added at the end of the workflow.',
),
parentStepConnectionOptions: z
.object({
type: z.string().optional(),
@@ -36,22 +40,56 @@ const createWorkflowVersionStepSchema = z.object({
})
.optional()
.describe('Optional position coordinates for the step'),
id: z.string().optional().describe('Optional step ID'),
});
export const createCreateWorkflowVersionStepTool = (
deps: Pick<WorkflowToolDependencies, 'workflowVersionStepService'>,
deps: Pick<
WorkflowToolDependencies,
'workflowVersionStepService' | 'workflowVersionStepHelpersService'
>,
context: WorkflowToolContext,
) => ({
name: 'create_workflow_version_step' as const,
description:
'Create a new step in a workflow version. This adds a step to the specified workflow version with the given configuration.',
'Create a new step in a workflow version. This adds a step to the specified workflow version with the given configuration. If parentStepId is not provided, the step will be appended at the end of the workflow.',
inputSchema: createWorkflowVersionStepSchema,
execute: async (parameters: CreateWorkflowVersionStepInput) => {
try {
let effectiveParentStepId = parameters.parentStepId;
if (!isDefined(effectiveParentStepId)) {
const workflowVersion =
await deps.workflowVersionStepHelpersService.getValidatedDraftWorkflowVersion(
{
workflowVersionId: parameters.workflowVersionId,
workspaceId: context.workspaceId,
},
);
const steps = workflowVersion.steps ?? [];
if (steps.length === 0) {
effectiveParentStepId = TRIGGER_STEP_ID;
} else {
const leafStep = steps.filter(
(step) =>
!isDefined(step.nextStepIds) || step.nextStepIds.length === 0,
);
if (leafStep.length > 1) {
effectiveParentStepId = undefined;
} else {
effectiveParentStepId = leafStep[0]?.id;
}
}
}
return await deps.workflowVersionStepService.createWorkflowVersionStep({
workspaceId: context.workspaceId,
input: parameters,
input: {
...parameters,
parentStepId: effectiveParentStepId,
},
});
} catch (error) {
return {
@@ -1,7 +1,4 @@
import {
workflowActionSchema,
workflowTriggerSchema,
} from 'twenty-shared/workflow';
import { workflowActionSchema } from 'twenty-shared/workflow';
import { z } from 'zod';
import type { UpdateWorkflowVersionStepInput } from 'src/engine/core-modules/workflow/dtos/update-workflow-version-step-input.dto';
@@ -15,7 +12,7 @@ const updateWorkflowVersionStepSchema = z.object({
.string()
.describe('The ID of the workflow version containing the step'),
step: z
.union([workflowTriggerSchema, workflowActionSchema])
.union([workflowActionSchema])
.describe('The updated step configuration'),
});
@@ -0,0 +1,51 @@
import { workflowTriggerSchema } from 'twenty-shared/workflow';
import { z } from 'zod';
import type { UpdateWorkflowVersionTriggerInput } from 'src/engine/core-modules/workflow/dtos/update-workflow-version-trigger-input.dto';
import {
type WorkflowToolContext,
type WorkflowToolDependencies,
} from 'src/modules/workflow/workflow-tools/types/workflow-tool-dependencies.type';
const updateWorkflowVersionTriggerSchema = z.object({
workflowVersionId: z
.string()
.describe('The ID of the workflow version containing the trigger'),
trigger: workflowTriggerSchema.describe('The updated trigger configuration'),
});
export const createUpdateWorkflowVersionTriggerTool = (
deps: Pick<WorkflowToolDependencies, 'workflowVersionStepHelpersService'>,
context: WorkflowToolContext,
) => ({
name: 'update_workflow_version_trigger' as const,
description:
'Update the trigger of a workflow version. This modifies the trigger configuration (e.g., changing trigger type, settings, or conditions).',
inputSchema: updateWorkflowVersionTriggerSchema,
execute: async (parameters: UpdateWorkflowVersionTriggerInput) => {
try {
await deps.workflowVersionStepHelpersService.getValidatedDraftWorkflowVersion(
{
workflowVersionId: parameters.workflowVersionId,
workspaceId: context.workspaceId,
},
);
await deps.workflowVersionStepHelpersService.updateWorkflowVersionStepsAndTrigger(
{
workspaceId: context.workspaceId,
workflowVersionId: parameters.workflowVersionId,
trigger: parameters.trigger,
},
);
return parameters.trigger;
} catch (error) {
return {
success: false,
error: error.message,
message: `Failed to update workflow version trigger: ${error.message}`,
};
}
},
});
@@ -2,12 +2,14 @@ import type { RecordPositionService } from 'src/engine/core-modules/record-posit
import type { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
import type { WorkflowSchemaWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-schema/workflow-schema.workspace-service';
import type { WorkflowVersionEdgeWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-edge/workflow-version-edge.workspace-service';
import type { WorkflowVersionStepHelpersWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step-helpers.workspace-service';
import type { WorkflowVersionStepWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version-step/workflow-version-step.workspace-service';
import type { WorkflowVersionWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-version/workflow-version.workspace-service';
import type { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service';
export type WorkflowToolDependencies = {
workflowVersionStepService: WorkflowVersionStepWorkspaceService;
workflowVersionStepHelpersService: WorkflowVersionStepHelpersWorkspaceService;
workflowVersionEdgeService: WorkflowVersionEdgeWorkspaceService;
workflowVersionService: WorkflowVersionWorkspaceService;
workflowTriggerService: WorkflowTriggerWorkspaceService;