diff --git a/src/runner.ts b/src/runner.ts index 28bc4e6..aab2998 100644 --- a/src/runner.ts +++ b/src/runner.ts @@ -1,5 +1,5 @@ import type { ZodError } from 'zod' -import type { FailureContext, Failure, Gate, Result, Step } from './types.js' +import type { Failure, FailureContext, Gate, Result, Step } from './types.js' /** * Format a ZodError into a human-readable reason string. @@ -17,7 +17,10 @@ function formatZodError(error: ZodError): string { * Run quality gates against a step's output. * Returns the first failure, or null if all gates pass. */ -function runGates(gates: Gate[], output: unknown): { reason: string; context?: unknown } | null { +function runGates( + gates: Gate[], + output: unknown, +): { reason: string; context?: unknown } | null { for (const gate of gates) { const result = gate(output) if (!result.ok) { diff --git a/src/types.ts b/src/types.ts index 7a38da4..eb60b1c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -4,9 +4,7 @@ import type { z } from 'zod' * Result of a quality gate check. * Gates are pure synchronous functions — no LLM calls, no async. */ -export type GateResult = - | { ok: true } - | { ok: false; reason: string; context?: unknown } +export type GateResult = { ok: true } | { ok: false; reason: string; context?: unknown } /** * A quality gate function. Receives a step's validated output @@ -83,9 +81,7 @@ export interface Failure { /** * Pipeline result type. Success or structured failure. */ -export type Result = - | { ok: true; value: T } - | { ok: false; failure: Failure } +export type Result = { ok: true; value: T } | { ok: false; failure: Failure } /** * Metadata returned by pipeline.describe(). diff --git a/tests/failure.test.ts b/tests/failure.test.ts index f035049..f04f20c 100644 --- a/tests/failure.test.ts +++ b/tests/failure.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { z } from 'zod' -import { defineStep, pipeline, PipelineError } from '../src/index.js' +import { PipelineError, defineStep, pipeline } from '../src/index.js' describe('structured failures', () => { it('schema_input failure has correct shape', async () => { diff --git a/tests/gates.test.ts b/tests/gates.test.ts index 134d42a..75d600c 100644 --- a/tests/gates.test.ts +++ b/tests/gates.test.ts @@ -45,9 +45,7 @@ describe('quality gates', () => { gates: [ (out) => (out.text.length > 0 ? { ok: true } : { ok: false, reason: 'empty' }), (out) => - out.text.length < 10 - ? { ok: true } - : { ok: false, reason: 'too long (max 10 chars)' }, + out.text.length < 10 ? { ok: true } : { ok: false, reason: 'too long (max 10 chars)' }, (_out) => ({ ok: false, reason: 'this gate should not run' }), ], run: async (input) => ({ text: input.text.repeat(5) }), diff --git a/tests/pipeline.test.ts b/tests/pipeline.test.ts index b10ec66..9bb8b64 100644 --- a/tests/pipeline.test.ts +++ b/tests/pipeline.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest' import { z } from 'zod' -import { defineStep, pipeline, PipelineError } from '../src/index.js' +import { PipelineError, defineStep, pipeline } from '../src/index.js' const double = defineStep({ name: 'double', @@ -9,7 +9,7 @@ const double = defineStep({ run: async (input) => ({ value: input.value * 2 }), }) -const toString = defineStep({ +const toText = defineStep({ name: 'to-string', input: z.object({ value: z.number() }), output: z.object({ text: z.string() }), @@ -28,7 +28,7 @@ describe('pipeline', () => { }) it('chains multiple steps', async () => { - const p = pipeline('multi').step(double).step(toString) + const p = pipeline('multi').step(double).step(toText) const result = await p.run({ value: 21 }) expect(result.ok).toBe(true) @@ -54,7 +54,7 @@ describe('pipeline', () => { name: 'bad-output', input: z.object({ x: z.number() }), output: z.object({ y: z.string() }), - run: async (input) => ({ y: input.x } as unknown as { y: string }), + run: async (input) => ({ y: input.x }) as unknown as { y: string }, }) const p = pipeline('bad-output').step(badStep) @@ -117,15 +117,15 @@ describe('pipeline', () => { }) it('describe() returns pipeline metadata', () => { - const p = pipeline('described').step(double).step(toString) + const p = pipeline('described').step(double).step(toText) const desc = p.describe() expect(desc.name).toBe('described') expect(desc.steps).toHaveLength(2) - expect(desc.steps[0]!.name).toBe('double') - expect(desc.steps[1]!.name).toBe('to-string') - expect(desc.steps[0]!.inputSchema).toHaveProperty('type', 'object') - expect(desc.steps[0]!.outputSchema).toHaveProperty('type', 'object') - expect(desc.steps[0]!.gates).toBe(0) + expect(desc.steps[0]?.name).toBe('double') + expect(desc.steps[1]?.name).toBe('to-string') + expect(desc.steps[0]?.inputSchema).toHaveProperty('type', 'object') + expect(desc.steps[0]?.outputSchema).toHaveProperty('type', 'object') + expect(desc.steps[0]?.gates).toBe(0) }) }) diff --git a/tests/retry.test.ts b/tests/retry.test.ts index b18ef3d..ddacd27 100644 --- a/tests/retry.test.ts +++ b/tests/retry.test.ts @@ -63,9 +63,9 @@ describe('retry with failure context', () => { expect(contexts).toHaveLength(2) expect(contexts[0]).toBeUndefined() // first attempt expect(contexts[1]).toBeDefined() // second attempt has context - expect(contexts[1]!.type).toBe('gate') - expect(contexts[1]!.attempt).toBe(1) - expect(contexts[1]!.reason).toContain('title too long') + expect(contexts[1]?.type).toBe('gate') + expect(contexts[1]?.attempt).toBe(1) + expect(contexts[1]?.reason).toContain('title too long') }) it('exhausts retries and returns structured failure', async () => {