Skip to main content
// Props
import { ContentPipeline } from "smithers-orchestrator";

type ContentPipelineProps = {
  id?: string;
  stages: ContentPipelineStage[];
  skipIf?: boolean;
  children: string | ReactNode; // initial prompt for stage[0]
};

type ContentPipelineStage = {
  id: string;
  agent: AgentLike;
  output: OutputTarget;
  label?: string;
};
export default smithers(() => (
  <Workflow name="blog-pipeline">
    <ContentPipeline
      stages={[
        { id: "outline", agent: outliner, output: outputs.outline, label: "Create outline" },
        { id: "draft", agent: writer, output: outputs.draft, label: "Write draft" },
        { id: "edit", agent: editor, output: outputs.edited, label: "Edit and polish" },
      ]}
    >
      Write a blog post about building AI workflows with React components.
    </ContentPipeline>
  </Workflow>
));

Notes

  • Each stage after the first depends on the previous via needs.
  • Stage id values must be unique within the workflow.

Source

The <ContentPipeline> implementation and the files it imports, straight from the package source. This section is generated; edit the source, not this block.
// @smithers-type-exports-begin
/** @typedef {import("./ContentPipelineProps.ts").ContentPipelineProps} ContentPipelineProps */
/** @typedef {import("./ContentPipelineStage.ts").ContentPipelineStage} ContentPipelineStage */
// @smithers-type-exports-end

import React from "react";
import { Sequence } from "./Sequence.js";
import { Task } from "./Task.js";
/**
 * Progressive content refinement: outline -> draft -> edit -> publish.
 *
 * Composes Sequence and Task to create a typed waterfall where each
 * stage is explicitly defined. Each Task uses `needs` to depend on
 * the previous stage, passing output forward through the pipeline.
 * @param {ContentPipelineProps} props
 */
export function ContentPipeline(props) {
    if (props.skipIf)
        return null;
    const { stages, children } = props;
    const taskElements = stages.map((stage, index) => {
        const taskProps = {
            id: stage.id,
            output: stage.output,
            agent: stage.agent,
            label: stage.label,
        };
        if (index === 0) {
            // First stage receives the initial prompt.
            return React.createElement(Task, taskProps, children);
        }
        // Subsequent stages depend on the previous stage.
        const prevStage = stages[index - 1];
        taskProps.needs = { previous: prevStage.id };
        return React.createElement(Task, taskProps, `Continue from the previous stage's output. Perform: ${stage.label ?? stage.id}`);
    });
    return React.createElement(Sequence, null, ...taskElements);
}