From d81a30f0512c7383e1e42dd6f26ecbe69d2297f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E6=A9=98?= Date: Tue, 5 May 2026 13:52:03 +0000 Subject: [PATCH] chore(workflow): post-extraction cleanup - IPC parse functions: replace whole-object 'as' casts with per-field narrowing - WorkflowConfig: remove duplicate from core, re-export from @uncaged/workflow - drainTimeoutMs: change from optional param to T | null convention - Remove duplicate WorkflowWorkerOutboundMessage, keep WorkflowChildToParentMessage Fixes #325 --- package.json | 3 ++- packages/core/package.json | 1 + packages/core/src/config.ts | 18 ++---------------- packages/workflow/src/index.ts | 1 - packages/workflow/src/ipc.ts | 27 +++++++++++---------------- packages/workflow/src/manager.ts | 10 +++++++--- packages/workflow/src/worker.ts | 4 ++-- pnpm-lock.yaml | 4 ++++ 8 files changed, 29 insertions(+), 39 deletions(-) diff --git a/package.json b/package.json index 15c974a..9108d7c 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "pnpm": { "overrides": { "@uncaged/nerve-core": "workspace:*", - "@uncaged/nerve-store": "workspace:*" + "@uncaged/nerve-store": "workspace:*", + "@uncaged/workflow": "workspace:*" } }, "scripts": { diff --git a/packages/core/package.json b/packages/core/package.json index e784889..4727056 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -20,6 +20,7 @@ "test": "vitest run" }, "dependencies": { + "@uncaged/workflow": "workspace:*", "yaml": "^2.8.3" }, "devDependencies": { diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index b33b7f6..6afbe63 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -1,23 +1,9 @@ import { parse } from "yaml"; +import type { DropOverflowConfig, QueueOverflowConfig, WorkflowConfig } from "@uncaged/workflow"; import { type Result, err, isPlainRecord, ok, parseDurationStringToMs } from "./util.js"; -/** - * Workflow queue/runtime limits parsed from nerve.yaml. - * Shapes match the standalone workflow package — core must not depend on it (#320). - */ -export type DropOverflowConfig = { - concurrency: number; - overflow: "drop"; -}; - -export type QueueOverflowConfig = { - concurrency: number; - overflow: "queue"; - maxQueue: number; -}; - -export type WorkflowConfig = DropOverflowConfig | QueueOverflowConfig; +export type { DropOverflowConfig, QueueOverflowConfig, WorkflowConfig }; /** Engine-wide fallback when nerve.yaml omits max_rounds (keep in sync with workflow package default). */ export const DEFAULT_ENGINE_MAX_ROUNDS = 100; diff --git a/packages/workflow/src/index.ts b/packages/workflow/src/index.ts index e2193fe..ef7b9b8 100644 --- a/packages/workflow/src/index.ts +++ b/packages/workflow/src/index.ts @@ -32,7 +32,6 @@ export type { WorkflowWorkerToParentMessage, WorkflowWorkerReadyMessage, WorkflowChildToParentMessage, - WorkflowWorkerOutboundMessage, } from "./ipc.js"; export { parseWorkflowParentMessage, diff --git a/packages/workflow/src/ipc.ts b/packages/workflow/src/ipc.ts index a216589..ac61f2e 100644 --- a/packages/workflow/src/ipc.ts +++ b/packages/workflow/src/ipc.ts @@ -100,11 +100,6 @@ export type WorkflowChildToParentMessage = | WorkflowWorkerReadyMessage | WorkflowWorkerToParentMessage; -/** Messages a workflow worker process may send upstream (ready + persisted workflow IPC). */ -export type WorkflowWorkerOutboundMessage = - | WorkflowWorkerReadyMessage - | WorkflowWorkerToParentMessage; - const WORKFLOW_PARENT_MSG_TYPES = new Set([ "start-thread", "resume-thread", @@ -135,12 +130,12 @@ function parseParentStartThread(obj: Record): Result): Result { @@ -148,18 +143,18 @@ function parseParentResumeThread(obj: Record): Result): Result { if (typeof obj.runId !== "string") { return err(new Error("'kill-thread' message missing string 'runId'")); } - return ok({ type: "kill-thread", runId: obj.runId } as KillThreadMessage); + return ok({ type: "kill-thread", runId: obj.runId as string }); } /** Validate and parse an unknown IPC message for a workflow worker process. */ diff --git a/packages/workflow/src/manager.ts b/packages/workflow/src/manager.ts index 1f22044..2c3b27e 100644 --- a/packages/workflow/src/manager.ts +++ b/packages/workflow/src/manager.ts @@ -58,8 +58,9 @@ export type WorkflowManager = { * Drain active threads for a workflow, then respawn its worker process. * Used for hot reload when bundled workflow output under dist/workflows// changes. * Waits up to `drainTimeoutMs` for threads to complete before force-killing. + * Pass `null` to use the manager default timeout. */ - drainAndRespawn: (workflowName: string, drainTimeoutMs?: number) => Promise; + drainAndRespawn: (workflowName: string, drainTimeoutMs?: number | null) => Promise; /** * Schedule a drain+respawn that waits for in-flight runs to finish first. * If no runs are active, drains immediately. Otherwise marks a pending reload @@ -450,13 +451,16 @@ export function createWorkflowManager( async function drainAndRespawn( workflowName: string, - drainTimeoutMs: number = DEFAULT_DRAIN_TIMEOUT_MS, + drainTimeoutMs: number | null = null, ): Promise { if (!trackedWorkflows.has(workflowName)) { return; } - const shutdownMs = Math.max(drainTimeoutMs, WORKER_SHUTDOWN_TIMEOUT_MS); + const shutdownMs = Math.max( + drainTimeoutMs ?? DEFAULT_DRAIN_TIMEOUT_MS, + WORKER_SHUTDOWN_TIMEOUT_MS, + ); hotReloadEvicting.add(workflowName); try { await runtime.evict(workflowName, { shutdownTimeoutMs: shutdownMs }); diff --git a/packages/workflow/src/worker.ts b/packages/workflow/src/worker.ts index c2ab882..da4da75 100644 --- a/packages/workflow/src/worker.ts +++ b/packages/workflow/src/worker.ts @@ -19,7 +19,7 @@ import { isPlainRecord } from "@uncaged/nerve-core"; import type { ThreadEventType, ThreadWorkflowMessage, - WorkflowWorkerOutboundMessage, + WorkflowChildToParentMessage, } from "./ipc.js"; import { parseWorkflowParentMessage } from "./ipc.js"; import type { @@ -37,7 +37,7 @@ import { ignoreSessionBroadcastSignals } from "./worker-signals.js"; // IPC helpers // --------------------------------------------------------------------------- -function send(msg: WorkflowWorkerOutboundMessage): void { +function send(msg: WorkflowChildToParentMessage): void { if (process.send) { process.send(msg); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 17d5c24..b1663bb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,6 +7,7 @@ settings: overrides: '@uncaged/nerve-core': workspace:* '@uncaged/nerve-store': workspace:* + '@uncaged/workflow': workspace:* importers: @@ -99,6 +100,9 @@ importers: packages/core: dependencies: + '@uncaged/workflow': + specifier: workspace:* + version: link:../workflow yaml: specifier: ^2.8.3 version: 2.8.3