Merge pull request 'fix: accept omitted condition in fallback transitions' (#378) from fix/fallback-transition-validation into main

This commit is contained in:
2026-05-22 07:56:18 +00:00
2 changed files with 23 additions and 3 deletions
+19 -2
View File
@@ -2,7 +2,12 @@ import { readFile } from "node:fs/promises";
import type { JSONSchema } from "@uncaged/json-cas"; import type { JSONSchema } from "@uncaged/json-cas";
import { putSchema, validate } from "@uncaged/json-cas"; import { putSchema, validate } from "@uncaged/json-cas";
import type { CasRef, RoleDefinition, WorkflowPayload } from "@uncaged/workflow-protocol"; import type {
CasRef,
RoleDefinition,
Transition,
WorkflowPayload,
} from "@uncaged/workflow-protocol";
import { parse } from "yaml"; import { parse } from "yaml";
import { import {
@@ -46,6 +51,18 @@ function isJsonSchema(value: unknown): value is JSONSchema {
return typeof value === "object" && value !== null && !Array.isArray(value); return typeof value === "object" && value !== null && !Array.isArray(value);
} }
/** Normalize graph transitions: ensure condition is null (not undefined) for fallback entries. */
function normalizeGraph(graph: Record<string, Transition[]>): Record<string, Transition[]> {
const result: Record<string, Transition[]> = {};
for (const [node, transitions] of Object.entries(graph)) {
result[node] = transitions.map((t) => ({
role: t.role,
condition: t.condition ?? null,
}));
}
return result;
}
async function resolveFrontmatterRef( async function resolveFrontmatterRef(
uwf: UwfStore, uwf: UwfStore,
roleName: string, roleName: string,
@@ -84,7 +101,7 @@ export async function materializeWorkflowPayload(
description: raw.description, description: raw.description,
roles, roles,
conditions: raw.conditions, conditions: raw.conditions,
graph: raw.graph, graph: normalizeGraph(raw.graph),
}; };
} }
+4 -1
View File
@@ -42,7 +42,10 @@ function isTransition(value: unknown): boolean {
return false; return false;
} }
const condition = value.condition; const condition = value.condition;
return typeof value.role === "string" && (condition === null || typeof condition === "string"); return (
typeof value.role === "string" &&
(condition === null || condition === undefined || typeof condition === "string")
);
} }
function isStringRecord(value: unknown, itemCheck: (item: unknown) => boolean): boolean { function isStringRecord(value: unknown, itemCheck: (item: unknown) => boolean): boolean {