feat(workflow)!: replace defineWorkflow<Agent>() with .for<Agent>() builder pattern for type-safe inputs - #635
Conversation
Replace defineWorkflow<Agent>() with defineWorkflow({ inputs: [...] }).for<Agent>()
so TypeScript can infer literal input names and enforce them on ctx.inputs at
compile time. Updates all workflows, SDK types, provider, docs, and tests.
Code Review: Workflow Builder Pattern RefactorThanks for this substantial refactor — the new builder pattern meaningfully improves type safety. Below is constructive feedback across the requested dimensions. StrengthsType-safe builder pattern — Thorough validation at compile time — Builtin workflows migrated cleanly — Concerns1. Interactive picker regression for free-form workflows ( The deletion of
2. Claude
3. Interactive 4. Migration path is abrupt Both #1 and #2 are breaking without deprecation warnings. Consider a minor release with:
TestsCoverage of the new builder is solid (
Gaps worth filling:
Performance & SecurityNo concerns. Validation is bounded and runs only at workflow compile/discovery time. Style / CLAUDE.md alignmentThe Overall this is a strong refactor. The ergonomic wins from literal type inference are real, and the test coverage of the new builder is good. My main ask is to address the two breaking changes (#1 picker, #2 Claude return type) before merging, since both fail silently in ways that will be hard for users to debug. |
Summary
Replaces
defineWorkflow<Agent>()withdefineWorkflow({ inputs: [...] }).for<Agent>()so TypeScript can infer literal input names from theinputsarray and enforce them onctx.inputsat compile time. Accessing an undeclared input key is now a compile-time error.Key Changes
.for<Agent>()method onWorkflowBuilder— type-only narrowing that preserves the inferred input name literals while still constraining agent-specific stage typesctx.inputs— changed fromRecord<string, string>to{ [K in N]?: string }whereNis the union of declared inputnameliterals; free-form workflows (noinputsarray) continue to accept any keyWorkflowContext,SessionContext,WorkflowOptions, andWorkflowDefinitionall carry the new input-name type parameterN extends stringworkflow-inputs.ts— standalone helper file consolidated into the main type definitionsheadless-test,hello-world,parallel-hello-world,ralph,deep-research-codebasemigrated to the new pattern.for()identity (type-only, same instance), chaining with.run().compile(), structured input key enforcement, and free-form fallbackworkflow-creatorskill references, SDK TypeScript reference, and README all reflect the new APIBreaking Changes
The agent type parameter moves from
defineWorkflow<Agent>()to a new.for<Agent>()chain step. Existing workflows must be updated:Inline
inputsdeclarations now produce typedctx.inputs: