// approval-gate.tsx
import { createSmithers, Task, Sequence } from "smithers-orchestrator";
import { ToolLoopAgent as Agent } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";
const { Workflow, smithers } = createSmithers({
draft: z.object({
title: z.string(),
content: z.string(),
}),
published: z.object({
url: z.string(),
publishedAt: z.string(),
}),
});
const writer = new Agent({
model: anthropic("claude-sonnet-4-5-20250929"),
instructions:
"You are a technical writer. Draft a blog post with a title and full content based on the given topic.",
});
const publisher = new Agent({
model: anthropic("claude-sonnet-4-5-20250929"),
instructions:
"You are a publishing agent. Take the approved draft and return a URL and timestamp for the published post.",
});
export default smithers((ctx) => {
const draft = ctx.outputMaybe("draft", { nodeId: "write-draft" });
return (
<Workflow name="approval-gate">
<Sequence>
{/* Step 1: Agent writes a draft */}
<Task id="write-draft" output="draft" agent={writer}>
Write a blog post about deterministic AI workflows and why resumability
matters for production systems.
</Task>
{/* Step 2: Human must approve before publishing */}
<Task
id="publish"
output="published"
agent={publisher}
needsApproval
label="Publish blog post"
>
Publish this approved draft:{"\n\n"}
Title: {draft?.title}
{"\n\n"}
{draft?.content}
</Task>
</Sequence>
</Workflow>
);
});