Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions packages/workflow-executor/src/adapters/server-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ export enum ServerStepExecutionTypeEnum {

interface ServerWorkflowStepBase {
type: ServerStepTypeEnum;
title: string;
prompt?: string;
// The orchestrator serializes missing BPMN attributes as null (DOM getAttribute), never omits.
title: string | null;
prompt?: string | null;
executionType: ServerStepExecutionTypeEnum;
automaticCompletion: boolean;
outgoing: ServerWorkflowTransition[];
Expand All @@ -50,7 +51,7 @@ export interface ServerWorkflowTaskBase extends ServerWorkflowStepBase {
type: ServerStepTypeEnum.Task;
taskType: ServerTaskTypeEnum;
isSubTask?: boolean;
prompt: string;
prompt: string | null;
outgoing: [ServerWorkflowTransition];
}

Expand Down
13 changes: 10 additions & 3 deletions packages/workflow-executor/src/types/validated/step-definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ export enum StepExecutionMode {
// Shared fields across all step types. executionType is intentionally excluded —
// each schema declares its own valid modes (most with .default().catch() for normalization;
// guidance deliberately omits .catch to fail loud on an unknown mode).
// The orchestrator serializes missing BPMN attributes as JSON null (DOM getAttribute), not as
// absent keys — accept both and normalize to undefined.
const optionalString = z
.string()
.nullish()
.transform(value => value ?? undefined);

const sharedFields = {
prompt: z.string().optional(),
aiConfigName: z.string().optional(),
title: z.string().optional(),
prompt: optionalString,
aiConfigName: optionalString,
title: optionalString,
};

// Use z.enum(EnumObject), not z.nativeEnum — the latter is deprecated in zod 4.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,38 @@ describe('toStepDefinition', () => {
options: ['Valid', 'AlsoValid'],
});
});

it('accepts a condition whose title and prompt are null (unnamed BPMN gateway)', () => {
const condition = makeCondition(
[
{ stepId: 's1', buttonText: 'Option A' },
{ stepId: 's2', buttonText: 'Option B' },
],
{ title: null, prompt: null },
);

expect(toStepDefinition(condition)).toMatchObject({
type: 'condition',
title: undefined,
prompt: undefined,
options: ['Option A', 'Option B'],
});
});
});

describe('null shared fields', () => {
it('accepts a task whose title and prompt are null (serialized missing BPMN attributes)', () => {
const task = makeTask({
title: null,
prompt: null,
});

expect(toStepDefinition(task)).toMatchObject({
type: 'read-record',
title: undefined,
prompt: undefined,
});
});
});

describe('unsupported step types', () => {
Expand Down
Loading