samai-sdk
Core concepts

Batch output & Standard Schema

generateObjectBatch() runs generateObject() across many inputs with bounded concurrency — the shape of a data-extraction pipeline. Anywhere the SDK takes a schema, you can pass zod or any Standard Schema V1 validator.

generateObjectBatch()

One bad input never aborts the rest of the batch; results come back in the same order as items regardless of completion order.

batch.ts
import { z } from "zod";
import { createClient, anthropic, generateObjectBatch } from "samai-sdk";

const client = createClient({ provider: anthropic({ apiKey: "..." }) });
const TicketSchema = z.object({
  category: z.enum(["billing", "bug", "feature_request", "other"]),
  urgency: z.enum(["low", "medium", "high"]),
});

const batch = await generateObjectBatch(client, {
  items: ["My card was charged twice", "App crashes on launch"],
  buildOptions: (ticketText) => ({
    model: "claude-sonnet-4-6",
    schema: TicketSchema,
    messages: [{ role: "user", content: `Classify: "${ticketText}"` }],
  }),
  concurrency: 5, // default 5
  onItemSettled: (item) => console.log(`item ${item.index}: ${item.status}`),
});

console.log(`${batch.succeeded}/${batch.results.length} succeeded`, batch.usage);
for (const r of batch.results) {
  if (r.status === "fulfilled") console.log(r.item, "->", r.result.object);
  else console.warn(r.item, "failed:", r.error.message);
}

Failing loudly on purpose

Pass throwOnAnyFailure: true to throw a GenerateObjectBatchError (carrying the full batchResult, including successful items) once every item has settled if any failed. For a concurrency cap shared across unrelated calls too, wrap the provider in withConcurrencyLimit() instead — the two compose.

Standard Schema support

Anywhere the SDK takes a schema — generateObject(), streamObject(), createSchemaGuardrail(), Agent.outputSchema — you can pass a zod schema, or any Standard Schema V1 validator (valibot 0.31+/1.x, arktype, etc.) instead. zod behavior is unchanged; this is purely additive.

valibot.ts
import * as v from "valibot";
import { createClient, anthropic, generateObject } from "samai-sdk";

const ReviewSchema = v.object({
  summary: v.string(),
  score: v.pipe(v.number(), v.minValue(1), v.maxValue(10)),
});

const result = await generateObject(client, {
  model: "claude-sonnet-4-6",
  schema: ReviewSchema, // a valibot schema — works exactly the same way as zod
  messages: [{ role: "user", content: "Extract structured data from this review: ..." }],
});

result.object.score; // fully typed via valibot's own inference

Known limitation

Validation needs no extra dependency. Generating the model-facing JSON-Schema instruction currently supports zod and valibot specifically — valibot needs the optional @valibot/to-json-schema peer dependency. Other Standard Schema vendors work for validation but need you to describe the output shape yourself via system. Tool parameters across the 8 provider adapters still require a zod schema specifically.