Note
The TypeScript optimization API lives in the @mv37/rollout/optimization subpath. GEPA, verifier scoring, dataset upload, and run bookkeeping all happen in the Rollout CLI — your endpoint only runs the agent and returns its output.
Define a target
defineOptimizationTarget describes one target: its id, its baseline artifact, and a run(task, candidate) function that executes your agent with the candidate applied and returns the output.
import { generateText } from "ai";import { openrouter } from "@openrouter/ai-sdk-provider";import { createOptimizationHandler, defineOptimizationTarget,} from "@mv37/rollout/optimization";const aimeSolver = defineOptimizationTarget({ id: "aime_solver", baseline: "Solve the problem and return only the final integer.", async run(task, candidate) { const result = await generateText({ model: openrouter("deepseek/deepseek-r1"), system: candidate.text, // GEPA proposes this prompt: String(task.instruction ?? task.input), }); return { output: result.text, metadata: { usage: result.usage } }; },});export const rolloutHandler = createOptimizationHandler([aimeSolver]);Create the handler
createOptimizationHandler takes one or more targets and returns a universal (Request) => Promise<Response>. It is transport-only and has no Node dependencies, so it runs on edge runtimes and Workers as well as Node.
Mount it anywhere
Because it is a plain fetch handler, it drops into any runtime:
// Next.js app router — app/api/rollout/route.tsexport const POST = rolloutHandler;// Hono / Cloudflare Workersapp.post("/rollout", (c) => rolloutHandler(c.req.raw));// Plain Node (>=20)import { createServer } from "node:http";import { createServerAdapter } from "@whatwg-node/server";createServer(createServerAdapter(rolloutHandler)).listen(3000);Point the CLI at it
Start your endpoint, then run the CLI with --target-url instead of --module. Everything else — dataset, verifier, reflection model — is identical to a Python run:
rollout optimize run \ --target-url http://localhost:3000/api/rollout \ --target aime_solver \ --dataset ./datasets/aime --verifier ./verifiers/exact.json \ --reflection-model openrouter/openai/gpt-4.1-miniWhat stays where
The CLI owns GEPA, verifier scoring, and uploads to Rollout. Your endpoint owns the agent and the model call. Provider keys stay in your own process — they never reach Rollout or the CLI host if those run elsewhere. See the control plane vs compute plane split for the full picture, and Datasets / Verifiers for the inputs the CLI needs.