Compose โ
compose() and pipe() chain agents into sequential pipelines. The output text of each agent becomes the prompt for the next. No graph required.
ts
import { compose, pipe, createAgent } from 'confused-ai';compose() โ simple pipeline โ
ts
import { createAgent, compose } from 'confused-ai';
const researcher = createAgent({
name: 'researcher',
instructions: 'Research topics and return raw findings.',
model: 'gpt-4o-mini',
apiKey: process.env.OPENAI_API_KEY!,
});
const writer = createAgent({
name: 'writer',
instructions: 'Turn research findings into polished reports.',
model: 'gpt-4o',
apiKey: process.env.OPENAI_API_KEY!,
});
// Always pass researcher output โ writer
const pipeline = compose(researcher, writer);
const result = await pipeline.run('Write a report on TypeScript 5.5');
// result.text โ the writer's final outputConditional hand-off โ
Use when to stop the pipeline early:
ts
const pipeline = compose(researcher, writer, {
// Only hand off to writer if research is substantial
when: (result) => result.text.length > 200,
});Transform output between stages โ
Use transform to reshape the output before passing it to the next agent:
ts
const pipeline = compose(researcher, writer, {
transform: (result) => `Here are the research findings:\n\n${result.text}`,
});pipe() โ fluent step-by-step builder โ
ts
import { pipe } from 'confused-ai';
const draft = createAgent({ name: 'drafter', instructions: 'Draft a blog post.', ... });
const editor = createAgent({ name: 'editor', instructions: 'Edit for clarity.', ... });
const publish = createAgent({ name: 'publisher', instructions: 'Format for publication.', ... });
const pipeline = pipe(draft)
.then(editor, { transform: (r) => `Edit this draft:\n\n${r.text}` })
.then(publish, { when: (r) => r.text.length > 50 });
const result = await pipeline.run('TypeScript 5.5 features');Three-stage document pipeline โ
ts
const summarizer = createAgent({ name: 'summarizer', instructions: 'Summarise this document in 3 bullet points.', ... });
const classifier = createAgent({ name: 'classifier', instructions: 'Classify the document: legal / technical / marketing.', ... });
const router = createAgent({ name: 'router', instructions: 'Given the classification, suggest the right team to handle this.', ... });
const result = await compose(summarizer, classifier, router, {
transform: (r, i) => i === 0
? `Summary:\n${r.text}\n\nPlease classify this document.`
: r.text,
}).run('CONTRACT-2024-001.pdf contents...');When to use compose vs graph โ
| Use case | Use |
|---|---|
| Linear, fixed-order pipeline | compose() / pipe() |
| Conditional branching | pipe(...).then(agent, { when }) or workflow-branching |
| Cycles, loops, or revisiting stages | Graph workflows |
| Parallel execution | Graph workflows |
| Durable checkpointing across process restarts | Graph workflows |
| Supervisor / consensus / handoff patterns | Orchestration |
Where to go next โ
- Workflow branching โ conditional routing between stages.
- Graph workflows โ DAG execution for complex multi-path flows.
- Orchestration โ supervisor patterns and agent handoffs.