diff --git a/packages/workflow-protocol/package.json b/packages/workflow-protocol/package.json new file mode 100644 index 0000000..c0aebdc --- /dev/null +++ b/packages/workflow-protocol/package.json @@ -0,0 +1,18 @@ +{ + "name": "@uncaged/workflow-protocol", + "version": "0.1.0", + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./src/index.ts" + } + }, + "peerDependencies": { + "zod": "^4.0.0" + }, + "devDependencies": { + "zod": "^4.0.0", + "typescript": "^5.8.3" + } +} diff --git a/packages/workflow-protocol/src/index.ts b/packages/workflow-protocol/src/index.ts new file mode 100644 index 0000000..5992630 --- /dev/null +++ b/packages/workflow-protocol/src/index.ts @@ -0,0 +1,40 @@ +// ── Types ────────────────────────────────────────────────────────── + +export type { + Result, + CasStore, + WorkflowRoleSchema, + WorkflowRoleDescriptor, + WorkflowDescriptor, + RoleMeta, + RoleOutput, + StartStep, + RoleStep, + ThreadContext, + ModeratorContext, + AgentContext, + ExtractContext, + WorkflowCompletion, + WorkflowResult, + LlmProvider, + ProviderConfig, + ResolvedModel, + WorkflowConfig, + ExtractFn, + AgentFn, + AgentBinding, + WorkflowRuntime, + WorkflowFn, + RoleDefinition, + Moderator, + WorkflowDefinition, + AdvanceOutcome, +} from "./types.js"; + +// ── Constants ────────────────────────────────────────────────────── + +export { START, END } from "./types.js"; + +// ── Constructor functions ────────────────────────────────────────── + +export { ok, err } from "./result.js"; diff --git a/packages/workflow-protocol/src/result.ts b/packages/workflow-protocol/src/result.ts new file mode 100644 index 0000000..f9b25c0 --- /dev/null +++ b/packages/workflow-protocol/src/result.ts @@ -0,0 +1,9 @@ +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 }; +} diff --git a/packages/workflow-protocol/src/types.ts b/packages/workflow-protocol/src/types.ts new file mode 100644 index 0000000..07bf57e --- /dev/null +++ b/packages/workflow-protocol/src/types.ts @@ -0,0 +1,167 @@ +import type * as z from "zod/v4"; + +// ── Constants ────────────────────────────────────────────────────── + +export const START = "__start__" as const; +export const END = "__end__" as const; + +// ── Result ───────────────────────────────────────────────────────── + +export type Result = { ok: true; value: T } | { ok: false; error: E }; + +// ── CAS ──────────────────────────────────────────────────────────── + +export type CasStore = { + put(content: string): Promise; + get(hash: string): Promise; + delete(hash: string): Promise; + list(): Promise; +}; + +// ── Workflow Descriptor ──────────────────────────────────────────── + +export type WorkflowRoleSchema = Record; + +export type WorkflowRoleDescriptor = { + description: string; + schema: WorkflowRoleSchema; +}; + +export type WorkflowDescriptor = { + description: string; + roles: Record; +}; + +// ── Role & Thread ────────────────────────────────────────────────── + +export type RoleMeta = Record>; + +export type RoleOutput = { + role: string; + contentHash: string; + meta: Record; + refs: string[]; +}; + +export type StartStep = { + role: typeof START; + content: string; + meta: { maxRounds: number }; + timestamp: number; +}; + +export type RoleStep = { + [K in keyof M & string]: { + role: K; + meta: M[K]; + contentHash: string; + refs: string[]; + timestamp: number; + }; +}[keyof M & string]; + +export type ThreadContext = { + threadId: string; + depth: number; + start: StartStep; + steps: RoleStep[]; +}; + +export type ModeratorContext = ThreadContext; + +export type AgentContext = ModeratorContext & { + currentRole: { + name: string; + systemPrompt: string; + }; +}; + +export type ExtractContext = AgentContext & { + agentContent: string; +}; + +// ── Workflow Completion ──────────────────────────────────────────── + +export type WorkflowCompletion = { + returnCode: number; + summary: string; +}; + +export type WorkflowResult = WorkflowCompletion & { + rootHash: string; +}; + +// ── LLM Provider ─────────────────────────────────────────────────── + +export type LlmProvider = { + baseUrl: string; + apiKey: string; + model: string; +}; + +export type ProviderConfig = { + baseUrl: string; + apiKey: string; +}; + +export type ResolvedModel = { + baseUrl: string; + apiKey: string; + model: string; +}; + +export type WorkflowConfig = { + maxDepth: number; + supervisorInterval: number; + providers: Record; + models: Record; +}; + +// ── Functions ────────────────────────────────────────────────────── + +export type ExtractFn = >( + schema: z.ZodType, + prompt: string, + ctx: ExtractContext, +) => Promise; + +export type AgentFn = (ctx: AgentContext) => Promise; + +export type AgentBinding = { + agent: AgentFn; + overrides: Partial> | null; +}; + +// ── Workflow Runtime & Definition ────────────────────────────────── + +export type WorkflowRuntime = { + cas: CasStore; + extract: ExtractFn; +}; + +export type WorkflowFn = ( + thread: ThreadContext, + runtime: WorkflowRuntime, +) => AsyncGenerator; + +export type RoleDefinition> = { + description: string; + systemPrompt: string; + extractPrompt: string; + schema: z.ZodType; + extractRefs: ((meta: Meta) => string[]) | null; +}; + +export type Moderator = ( + ctx: ModeratorContext, +) => (keyof M & string) | typeof END; + +export type WorkflowDefinition = { + description: string; + roles: { [K in keyof M & string]: RoleDefinition }; + moderator: Moderator; +}; + +export type AdvanceOutcome = + | { kind: "complete"; completion: WorkflowCompletion } + | { kind: "yield"; output: RoleOutput; step: RoleStep }; diff --git a/packages/workflow-protocol/tsconfig.json b/packages/workflow-protocol/tsconfig.json new file mode 100644 index 0000000..75eba9f --- /dev/null +++ b/packages/workflow-protocol/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "include": ["src"] +}