diff --git a/packages/workflow-runtime/package.json b/packages/workflow-runtime/package.json index d3d5f70..37833b9 100644 --- a/packages/workflow-runtime/package.json +++ b/packages/workflow-runtime/package.json @@ -7,6 +7,9 @@ "scripts": { "test": "bun test" }, + "dependencies": { + "@uncaged/workflow-protocol": "workspace:*" + }, "peerDependencies": { "zod": "^4.0.0" }, diff --git a/packages/workflow-runtime/src/create-workflow.ts b/packages/workflow-runtime/src/create-workflow.ts index a899edd..3ef9fa3 100644 --- a/packages/workflow-runtime/src/create-workflow.ts +++ b/packages/workflow-runtime/src/create-workflow.ts @@ -1,6 +1,7 @@ import type * as z from "zod/v4"; import { + type AdvanceOutcome, type AgentBinding, type AgentContext, type AgentFn, @@ -48,10 +49,6 @@ function agentForRole(binding: AgentBinding, roleName: string): AgentFn { return overrideFn !== undefined ? overrideFn : binding.agent; } -type AdvanceOutcome = - | { kind: "complete"; completion: WorkflowCompletion } - | { kind: "yield"; output: RoleOutput; step: RoleStep }; - async function advanceOneRound( def: Pick, "roles" | "moderator">, binding: AgentBinding, diff --git a/packages/workflow-runtime/src/index.ts b/packages/workflow-runtime/src/index.ts index c1f5c8b..37366ad 100644 --- a/packages/workflow-runtime/src/index.ts +++ b/packages/workflow-runtime/src/index.ts @@ -1,29 +1,29 @@ export { createWorkflow } from "./create-workflow.js"; export { err, ok } from "./result.js"; export type { - AgentBinding, - AgentContext, - AgentFn, - CasStore, - ExtractContext, - ExtractFn, - LlmProvider, - Moderator, - ModeratorContext, - Result, - RoleDefinition, - RoleMeta, - RoleOutput, - RoleStep, - StartStep, - ThreadContext, - WorkflowCompletion, - WorkflowDefinition, - WorkflowDescriptor, - WorkflowFn, - WorkflowResult, - WorkflowRoleDescriptor, - WorkflowRoleSchema, - WorkflowRuntime, + AgentBinding, + AgentContext, + AgentFn, + CasStore, + ExtractContext, + ExtractFn, + LlmProvider, + Moderator, + ModeratorContext, + Result, + RoleDefinition, + RoleMeta, + RoleOutput, + RoleStep, + StartStep, + ThreadContext, + WorkflowCompletion, + WorkflowDefinition, + WorkflowDescriptor, + WorkflowFn, + WorkflowResult, + WorkflowRoleDescriptor, + WorkflowRoleSchema, + WorkflowRuntime, } from "./types.js"; export { END, START } from "./types.js"; diff --git a/packages/workflow-runtime/src/result.ts b/packages/workflow-runtime/src/result.ts index 6f92f67..0c2f52f 100644 --- a/packages/workflow-runtime/src/result.ts +++ b/packages/workflow-runtime/src/result.ts @@ -1,9 +1,2 @@ -import type { Result } from "./types.js"; - -export function ok(value: T): Result { - return { ok: true, value }; -} - -export function err(error: E): Result { - return { ok: false, error }; -} +// Re-export from protocol for backward compatibility. +export { err, ok } from "@uncaged/workflow-protocol"; diff --git a/packages/workflow-runtime/src/types.ts b/packages/workflow-runtime/src/types.ts index c6f3f2c..e4d5e53 100644 --- a/packages/workflow-runtime/src/types.ts +++ b/packages/workflow-runtime/src/types.ts @@ -1,165 +1,33 @@ -import type * as z from "zod/v4"; +// Re-export all types from the protocol package. +// This file exists for backward compatibility — downstream code that +// imports from "@uncaged/workflow-runtime" continues to work. -/** Sentinel values for automaton control flow. */ -export const START = "__start__" as const; -export const END = "__end__" as const; +export type { + AgentBinding, + AgentContext, + AgentFn, + AdvanceOutcome, + CasStore, + ExtractContext, + ExtractFn, + LlmProvider, + Moderator, + ModeratorContext, + Result, + RoleDefinition, + RoleMeta, + RoleOutput, + RoleStep, + StartStep, + ThreadContext, + WorkflowCompletion, + WorkflowDefinition, + WorkflowDescriptor, + WorkflowFn, + WorkflowResult, + WorkflowRoleDescriptor, + WorkflowRoleSchema, + WorkflowRuntime, +} from "@uncaged/workflow-protocol"; -export type CasStore = { - put(content: string): Promise; - get(hash: string): Promise; - delete(hash: string): Promise; - list(): Promise; -}; - -/** JSON Schema fragment describing one role's `meta` shape (subset supported by code generation). */ -export type WorkflowRoleSchema = Record; - -export type WorkflowRoleDescriptor = { - description: string; - schema: WorkflowRoleSchema; -}; - -/** Workflow metadata exported as `export const descriptor` from `.esm.js` bundles. */ -export type WorkflowDescriptor = { - description: string; - roles: Record; -}; - -/** Expected success/failure outcome without throwing for recoverable errors. */ -export type Result = { ok: true; value: T } | { ok: false; error: E }; - -/** Maps role names → their meta types. Single generic drives all inference. */ -export type RoleMeta = Record>; - -/** OpenAI-compatible LLM endpoint used for structured meta extraction. */ -export type LlmProvider = { - baseUrl: string; - apiKey: string; - model: string; -}; - -/** What each generator yield produces — one role's output (engine adds `timestamp` when persisting). */ -export type RoleOutput = { - role: string; - /** CAS hash of the serialized Merkle content node for this step's body text. */ - contentHash: string; - meta: Record; - /** CAS hashes produced or consumed by this step (for GC traceability). */ - refs: string[]; -}; - -/** Generator completion value from a workflow bundle (`run` export). Root hash is added by the engine. */ -export type WorkflowCompletion = { - returnCode: number; - summary: string; -}; - -/** Final thread outcome from executeThread, including Merkle thread root CAS hash. */ -export type WorkflowResult = WorkflowCompletion & { - rootHash: string; -}; - -/** Runtime dependencies passed to a workflow bundle's `run` export (engine-provided). */ -export type WorkflowRuntime = { - /** Global CAS store for Merkle content blobs (role step bodies). */ - cas: CasStore; - /** Structured meta extraction; resolved from workflow.yaml `extract` scene by the engine. */ - extract: ExtractFn; -}; - -/** Bundle contract — named export `run` is a function returning an AsyncGenerator. */ -export type WorkflowFn = ( - thread: ThreadContext, - runtime: WorkflowRuntime, -) => AsyncGenerator; - -/** Engine start frame: initial prompt + thread identity. */ -export type StartStep = { - role: typeof START; - content: string; - meta: { maxRounds: number }; - timestamp: number; -}; - -/** A completed role step in the thread. */ -export type RoleStep = { - [K in keyof M & string]: { - role: K; - meta: M[K]; - contentHash: string; - refs: string[]; - timestamp: number; - }; -}[keyof M & string]; - -/** Thread runtime context shared by moderator/agent/extractor phases. */ -export type ThreadContext = { - threadId: string; - /** Nesting depth for workflow-as-agent chains; root threads use `0`. */ - depth: number; - start: StartStep; - steps: RoleStep[]; -}; - -/** Phase 1: Moderator decides next role. */ -export type ModeratorContext = ThreadContext; - -/** Phase 2: Agent executes — knows its role and prompt. */ -export type AgentContext = ModeratorContext & { - currentRole: { - name: string; - systemPrompt: string; - }; -}; - -/** Phase 3: Extractor runs — has agent output; the extraction instruction is a separate argument to the extract function. */ -export type ExtractContext = AgentContext & { - agentContent: string; -}; - -export type ExtractFn = >( - schema: z.ZodType, - prompt: string, - ctx: ExtractContext, -) => Promise; - -/** Raw string output from an LLM/CLI adapter; meta is extracted by the engine. */ -export type AgentFn = (ctx: AgentContext) => Promise; - -/** Runtime agent assignment (explicit null when no per-role overrides). */ -export type AgentBinding = { - agent: AgentFn; - overrides: Partial> | null; -}; - -/** Role wiring: prompts, schema, and human-readable description. */ -export type RoleDefinition> = { - description: string; - systemPrompt: string; - extractPrompt: string; - schema: z.ZodType; - /** When non-null, produces CAS hashes to persist on this role's steps (see `RoleOutput.refs`). */ - extractRefs: ((meta: Meta) => string[]) | null; -}; - -/** - * The Moderator — a pure routing function. - * Receives the full thread context (start + all prior steps). - * On initial call, `steps` is empty. - * Returns the next role name or END to terminate. - */ -export type Moderator = ( - ctx: ModeratorContext, -) => (keyof M & string) | typeof END; - -/** Complete workflow definition as authored by users. */ -export type WorkflowDefinition = { - description: string; - roles: { [K in keyof M & string]: RoleDefinition }; - moderator: Moderator; -}; - -/** Internal outcome of advancing one moderator round inside {@link createWorkflow}. */ -export type AdvanceOutcome = - | { kind: "complete"; completion: WorkflowCompletion } - | { kind: "yield"; output: RoleOutput; step: RoleStep }; +export { END, START } from "@uncaged/workflow-protocol";