From fc7d482b4ffc9508bf1028a8a509a85cee7aee4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=A9=98?= Date: Thu, 21 May 2026 01:41:20 +0000 Subject: [PATCH] feat: add four-phase role description (identity/prepare/execute/report) - Extend RoleDefinition with identity, prepare, execute, report fields - Make systemPrompt optional (nullable) for four-phase workflows - Update ROLE_DEFINITION JSON Schema (all new fields optional) - Update validate.ts to accept new fields - Update workflow.ts to strip null fields before CAS storage - Update thread read to prefer identity over systemPrompt - Add --version flag to uwf CLI - Bump all packages to 0.5.0 Refs #359 --- packages/cli-workflow/package.json | 2 +- packages/cli-workflow/src/cli.ts | 4 +++- packages/cli-workflow/src/commands/thread.ts | 3 ++- packages/cli-workflow/src/commands/workflow.ts | 15 +++++++++++++-- packages/cli-workflow/src/validate.ts | 14 +++++++++++--- packages/workflow-agent-hermes/package.json | 2 +- packages/workflow-agent-kit/package.json | 2 +- packages/workflow-moderator/package.json | 2 +- packages/workflow-protocol/package.json | 2 +- packages/workflow-protocol/src/schemas.ts | 6 +++++- packages/workflow-protocol/src/types.ts | 6 +++++- packages/workflow-util/package.json | 2 +- 12 files changed, 45 insertions(+), 15 deletions(-) diff --git a/packages/cli-workflow/package.json b/packages/cli-workflow/package.json index 4b30e2c..41e1266 100644 --- a/packages/cli-workflow/package.json +++ b/packages/cli-workflow/package.json @@ -1,6 +1,6 @@ { "name": "@uncaged/cli-workflow", - "version": "0.1.0", + "version": "0.5.0", "files": [ "src", "dist", diff --git a/packages/cli-workflow/src/cli.ts b/packages/cli-workflow/src/cli.ts index 4201404..995fb67 100755 --- a/packages/cli-workflow/src/cli.ts +++ b/packages/cli-workflow/src/cli.ts @@ -45,7 +45,9 @@ function runAction(action: () => Promise): void { const program = new Command(); -program.name("uwf").description("Stateless workflow CLI"); +// eslint-disable-next-line -- dynamic import for version +const pkg = await import("../package.json", { with: { type: "json" } }); +program.name("uwf").description("Stateless workflow CLI").version(pkg.default.version, "-V, --version"); program.option("--format ", "Output format: json or yaml", "json"); const workflow = program.command("workflow").description("Workflow registry and CAS"); diff --git a/packages/cli-workflow/src/commands/thread.ts b/packages/cli-workflow/src/commands/thread.ts index 1cf6d22..99c0f98 100644 --- a/packages/cli-workflow/src/commands/thread.ts +++ b/packages/cli-workflow/src/commands/thread.ts @@ -500,7 +500,8 @@ function formatThreadReadMarkdown(options: { ]; const roleDef = workflow.roles[item.payload.role]; if (roleDef) { - stepLines.push("", "### Prompt", "", roleDef.systemPrompt); + const prompt = roleDef.identity ?? roleDef.systemPrompt ?? ""; + stepLines.push("", "### Prompt", "", prompt); } if (item.payload.detail) { const content = extractLastAssistantContent(uwf, item.payload.detail); diff --git a/packages/cli-workflow/src/commands/workflow.ts b/packages/cli-workflow/src/commands/workflow.ts index d624159..c48012c 100644 --- a/packages/cli-workflow/src/commands/workflow.ts +++ b/packages/cli-workflow/src/commands/workflow.ts @@ -67,11 +67,22 @@ async function materializeWorkflowPayload( `${raw.name}.${roleName}`, role.outputSchema, ); - roles[roleName] = { + const roleDef: RoleDefinition = { description: role.description, - systemPrompt: role.systemPrompt, + systemPrompt: role.systemPrompt ?? null, + identity: role.identity ?? null, + prepare: role.prepare ?? null, + execute: role.execute ?? null, + report: role.report ?? null, outputSchema, }; + // Strip null fields so CAS payload stays lean and schema-valid + for (const key of ["systemPrompt", "identity", "prepare", "execute", "report"] as const) { + if (roleDef[key] === null) { + delete (roleDef as Record)[key]; + } + } + roles[roleName] = roleDef; } return { name: raw.name, diff --git a/packages/cli-workflow/src/validate.ts b/packages/cli-workflow/src/validate.ts index d106dcf..be63e40 100644 --- a/packages/cli-workflow/src/validate.ts +++ b/packages/cli-workflow/src/validate.ts @@ -16,9 +16,17 @@ function isRoleDefinition(value: unknown): boolean { } const outputSchema = value.outputSchema; const schemaOk = isRecord(outputSchema) && typeof outputSchema.type === "string"; - return ( - typeof value.description === "string" && typeof value.systemPrompt === "string" && schemaOk - ); + const hasSystemPrompt = + value.systemPrompt === undefined || value.systemPrompt === null || typeof value.systemPrompt === "string"; + const hasIdentity = + value.identity === undefined || value.identity === null || typeof value.identity === "string"; + const hasPrepare = + value.prepare === undefined || value.prepare === null || typeof value.prepare === "string"; + const hasExecute = + value.execute === undefined || value.execute === null || typeof value.execute === "string"; + const hasReport = + value.report === undefined || value.report === null || typeof value.report === "string"; + return typeof value.description === "string" && hasSystemPrompt && hasIdentity && hasPrepare && hasExecute && hasReport && schemaOk; } function isConditionDefinition(value: unknown): boolean { diff --git a/packages/workflow-agent-hermes/package.json b/packages/workflow-agent-hermes/package.json index 9a11a28..62f3bd6 100644 --- a/packages/workflow-agent-hermes/package.json +++ b/packages/workflow-agent-hermes/package.json @@ -1,6 +1,6 @@ { "name": "@uncaged/workflow-agent-hermes", - "version": "0.1.0", + "version": "0.5.0", "files": [ "src", "dist", diff --git a/packages/workflow-agent-kit/package.json b/packages/workflow-agent-kit/package.json index f1bc5b4..1be9724 100644 --- a/packages/workflow-agent-kit/package.json +++ b/packages/workflow-agent-kit/package.json @@ -1,6 +1,6 @@ { "name": "@uncaged/workflow-agent-kit", - "version": "0.1.0", + "version": "0.5.0", "files": [ "src", "dist", diff --git a/packages/workflow-moderator/package.json b/packages/workflow-moderator/package.json index 59aa336..db8b99f 100644 --- a/packages/workflow-moderator/package.json +++ b/packages/workflow-moderator/package.json @@ -1,6 +1,6 @@ { "name": "@uncaged/workflow-moderator", - "version": "0.1.0", + "version": "0.5.0", "files": [ "src", "dist", diff --git a/packages/workflow-protocol/package.json b/packages/workflow-protocol/package.json index e56251d..acf290f 100644 --- a/packages/workflow-protocol/package.json +++ b/packages/workflow-protocol/package.json @@ -1,6 +1,6 @@ { "name": "@uncaged/workflow-protocol", - "version": "0.1.0", + "version": "0.5.0", "files": [ "src", "dist", diff --git a/packages/workflow-protocol/src/schemas.ts b/packages/workflow-protocol/src/schemas.ts index 08cf28c..672de87 100644 --- a/packages/workflow-protocol/src/schemas.ts +++ b/packages/workflow-protocol/src/schemas.ts @@ -2,10 +2,14 @@ import type { JSONSchema } from "@uncaged/json-cas"; const ROLE_DEFINITION: JSONSchema = { type: "object", - required: ["description", "systemPrompt", "outputSchema"], + required: ["description", "outputSchema"], properties: { description: { type: "string" }, systemPrompt: { type: "string" }, + identity: { type: "string" }, + prepare: { type: "string" }, + execute: { type: "string" }, + report: { type: "string" }, outputSchema: { type: "string", format: "cas_ref" }, }, additionalProperties: false, diff --git a/packages/workflow-protocol/src/types.ts b/packages/workflow-protocol/src/types.ts index 34f4822..1996c36 100644 --- a/packages/workflow-protocol/src/types.ts +++ b/packages/workflow-protocol/src/types.ts @@ -18,7 +18,11 @@ export type StepRecord = { export type RoleDefinition = { description: string; - systemPrompt: string; + systemPrompt: string | null; + identity: string | null; + prepare: string | null; + execute: string | null; + report: string | null; outputSchema: CasRef; }; diff --git a/packages/workflow-util/package.json b/packages/workflow-util/package.json index a74148a..5a17e96 100644 --- a/packages/workflow-util/package.json +++ b/packages/workflow-util/package.json @@ -1,6 +1,6 @@ { "name": "@uncaged/workflow-util", - "version": "0.5.0-alpha.4", + "version": "0.5.0", "files": [ "src", "dist",