Skip to content

Commit fa3d0cd

Browse files
authored
Force uuids in AI workflow tools (#20010)
- Add .uuid() Zod validation to all AI workflow tool schemas (workflowVersionId, workflowId, stepId, edge target) so the AI model is constrained to use valid UUIDs instead of human-readable strings like step-find-stale-leads - Fixes Sentry noise from Invalid UUID errors triggered when workflows created with non-UUID step IDs are later edited via GraphQL mutations that enforce UUID scalars Will fix https://twenty-v7.sentry.io/issues/7240446584/events/05c7782655a34f4a8f5fc889164026ab/?project=4507072499810304&referrer=previous-event
1 parent 652930e commit fa3d0cd

12 files changed

Lines changed: 43 additions & 19 deletions

packages/twenty-server/src/modules/workflow/workflow-tools/tools/activate-workflow-version.tool.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
const activateWorkflowVersionSchema = z.object({
99
workflowVersionId: z
1010
.string()
11-
.describe('The ID of the workflow version to activate'),
11+
.uuid()
12+
.describe('The UUID of the workflow version to activate'),
1213
});
1314

1415
type ActivateWorkflowVersionInput = z.infer<

packages/twenty-server/src/modules/workflow/workflow-tools/tools/compute-step-output-schema.tool.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ const computeStepOutputSchemaSchema = z.object({
1515
step: z
1616
.union([workflowTriggerSchema, workflowActionSchema])
1717
.describe('The workflow step configuration'),
18-
workflowVersionId: z.string().describe('The ID of the workflow version'),
18+
workflowVersionId: z
19+
.string()
20+
.uuid()
21+
.describe('The UUID of the workflow version'),
1922
});
2023

2124
export const createComputeStepOutputSchemaTool = (

packages/twenty-server/src/modules/workflow/workflow-tools/tools/create-draft-from-workflow-version.tool.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import {
66
} from 'src/modules/workflow/workflow-tools/types/workflow-tool-dependencies.type';
77

88
const createDraftFromWorkflowVersionSchema = z.object({
9-
workflowId: z.string().describe('The ID of the workflow'),
9+
workflowId: z.string().uuid().describe('The UUID of the workflow'),
1010
workflowVersionIdToCopy: z
1111
.string()
12-
.describe('The ID of the workflow version to create a draft from'),
12+
.uuid()
13+
.describe('The UUID of the workflow version to create a draft from'),
1314
});
1415

1516
type CreateDraftFromWorkflowVersionInput = z.infer<

packages/twenty-server/src/modules/workflow/workflow-tools/tools/create-workflow-version-edge.tool.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import {
77
} from 'src/modules/workflow/workflow-tools/types/workflow-tool-dependencies.type';
88

99
const createWorkflowVersionEdgeSchema = z.object({
10-
workflowVersionId: z.string().describe('The ID of the workflow version'),
11-
source: z.string().describe('The ID of the source step'),
12-
target: z.string().describe('The ID of the target step'),
10+
workflowVersionId: z
11+
.string()
12+
.uuid()
13+
.describe('The UUID of the workflow version'),
14+
source: z
15+
.union([z.literal('trigger'), z.string().uuid()])
16+
.describe('The source step: "trigger" or a step UUID'),
17+
target: z.string().uuid().describe('The UUID of the target step'),
1318
sourceConnectionOptions: z
1419
.object({
1520
connectedStepType: z.literal(WorkflowActionType.ITERATOR),

packages/twenty-server/src/modules/workflow/workflow-tools/tools/create-workflow-version-step.tool.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ import {
1313
const baseStepFields = {
1414
workflowVersionId: z
1515
.string()
16-
.describe('The ID of the workflow version to add the step to'),
16+
.uuid()
17+
.describe('The UUID of the workflow version to add the step to'),
1718
parentStepId: z
1819
.string()
1920
.optional()
2021
.describe(
21-
'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.',
22+
'Optional ID of the parent step this step should come after (UUID, or "trigger" for the trigger step). If not provided, the step will be added at the end of the workflow.',
2223
),
2324
parentStepConnectionOptions: z
2425
.object({

packages/twenty-server/src/modules/workflow/workflow-tools/tools/deactivate-workflow-version.tool.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
const deactivateWorkflowVersionSchema = z.object({
99
workflowVersionId: z
1010
.string()
11-
.describe('The ID of the workflow version to deactivate'),
11+
.uuid()
12+
.describe('The UUID of the workflow version to deactivate'),
1213
});
1314

1415
type DeactivateWorkflowVersionInput = z.infer<

packages/twenty-server/src/modules/workflow/workflow-tools/tools/delete-workflow-version-edge.tool.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ import {
77
} from 'src/modules/workflow/workflow-tools/types/workflow-tool-dependencies.type';
88

99
const deleteWorkflowVersionEdgeSchema = z.object({
10-
workflowVersionId: z.string().describe('The ID of the workflow version'),
11-
source: z.string().describe('The ID of the source step'),
12-
target: z.string().describe('The ID of the target step'),
10+
workflowVersionId: z
11+
.string()
12+
.uuid()
13+
.describe('The UUID of the workflow version'),
14+
source: z
15+
.union([z.literal('trigger'), z.string().uuid()])
16+
.describe('The source step: "trigger" or a step UUID'),
17+
target: z.string().uuid().describe('The UUID of the target step'),
1318
sourceConnectionOptions: z
1419
.object({
1520
connectedStepType: z.literal(WorkflowActionType.ITERATOR),

packages/twenty-server/src/modules/workflow/workflow-tools/tools/delete-workflow-version-step.tool.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import {
88
const deleteWorkflowVersionStepSchema = z.object({
99
workflowVersionId: z
1010
.string()
11-
.describe('The ID of the workflow version containing the step'),
12-
stepId: z.string().describe('The ID of the step to delete'),
11+
.uuid()
12+
.describe('The UUID of the workflow version containing the step'),
13+
stepId: z.string().uuid().describe('The UUID of the step to delete'),
1314
});
1415

1516
type DeleteWorkflowVersionStepInput = z.infer<

packages/twenty-server/src/modules/workflow/workflow-tools/tools/get-workflow-current-version.tool.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import {
1515
const getWorkflowCurrentVersionSchema = z.object({
1616
workflowId: z
1717
.string()
18-
.describe('The ID of the workflow to get the current version for'),
18+
.uuid()
19+
.describe('The UUID of the workflow to get the current version for'),
1920
});
2021

2122
type GetWorkflowCurrentVersionInput = z.infer<

packages/twenty-server/src/modules/workflow/workflow-tools/tools/update-workflow-version-positions.tool.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import {
77
} from 'src/modules/workflow/workflow-tools/types/workflow-tool-dependencies.type';
88

99
const updateWorkflowVersionPositionsSchema = z.object({
10-
workflowVersionId: z.string().describe('The ID of the workflow version'),
10+
workflowVersionId: z
11+
.string()
12+
.uuid()
13+
.describe('The UUID of the workflow version'),
1114
positions: z
1215
.array(
1316
z.object({

0 commit comments

Comments
 (0)