NylorunDocsBeta
BuildCompose

Pipe

Run agents, HTTP tools and flows in order, each one's output the next one's input.

.pipe() adds one stage per child, in order. A child is an agent, an HTTP tool, a flow agent or a flow(). The first stage gets the flow's input, and each later stage gets the previous stage's output.

import { Agent, http } from "@nylorun/agents";
import { z } from "zod";

const researcher = Agent({ id: "researcher" })
  .instructions("Research the topic. Return { findings }.")
  .output(z.object({ findings: z.string() }));
const analyst = Agent({ id: "analyst" })
  .instructions("Summarize the findings. Return { summary }.")
  .output(z.object({ summary: z.string() }));
const publish = http({
  name: "publish",
  input: z.object({ summary: z.string() }),
  output: z.object({ ok: z.boolean() }),
  url: "https://reports.example.com/publish",
});

export const report = Agent({ id: "report" }).pipe(researcher, analyst, publish);

Repeated calls add more stages: .pipe(researcher).pipe(analyst, publish) is the same flow.

Shape the data in the output

Nothing runs between stages, so each stage's output is exactly what the next one receives. Give each agent an .output() schema with the fields the next stage needs, and say in its instructions what to return. An HTTP stage's input must match the previous output; see HTTP stages.

An agent after the first stage also sees the flow's input, as the original request, before its own input.

Ids

A stage's id is the agent's id or the tool's name. Rename a child with .withId() when the same agent appears more than once:

.pipe(writer, editor, writer.withId("final-writer"))

The renamed stage runs in its own session (final-writer), with the same definition.

A flow agent's output is its last stage's output. Runtime checkpoints every stage, so a resumed flow does not repeat completed work.

See the shipped chain example, then learn how to route with Switch.

On this page