Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ const triggerActionPatchSchema = z
// Whether the native submit actually executed the action, or only created an approval request
// (non-blocking): downstream AI steps must be told an awaiting-approval action did NOT run.
submissionOutcome: z.enum(['executed', 'pending-approval']).optional(),
// The approval request the native submit filed, when submissionOutcome is 'pending-approval'.
// Persisted so the run panel can deep-link to it (parity with the Full-AI path).
approvalRequest: z
.object({ id: z.string().min(1) })
.strict()
.optional(),
})
.strict();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,30 @@ describe('patchBodySchemas', () => {
expect(parsed).toEqual({ userConfirmed: false });
});

it('accepts a pending-approval submit carrying the approval request id', () => {
const parsed = schema.parse({
userConfirmed: true,
submissionOutcome: 'pending-approval',
approvalRequest: { id: 'appr-1' },
});

expect(parsed).toEqual({
userConfirmed: true,
submissionOutcome: 'pending-approval',
approvalRequest: { id: 'appr-1' },
});
});

it('rejects an approvalRequest with an empty id', () => {
expect(() => schema.parse({ userConfirmed: true, approvalRequest: { id: '' } })).toThrow();
});

it('rejects extra keys inside approvalRequest (strict)', () => {
expect(() =>
schema.parse({ userConfirmed: true, approvalRequest: { id: 'a', extra: 'leak' } }),
).toThrow();
});

it('rejects unknown fields (strict schema)', () => {
expect(() =>
schema.parse({ userConfirmed: true, actionResult: {}, extra: 'leak' }),
Expand Down
Loading