Skip to the content.

Structured generation

Apple’s guided generation constrains decoding to a schema, so the output is always valid for the schema, not “usually valid JSON”. Swift uses @Generable macros; from JavaScript you pass a runtime schema, which this package converts to DynamicGenerationSchema → GenerationSchema.

With Zod (or any Standard JSON Schema library)

import { z } from 'zod';

const Person = z.object({
  name: z.string().describe('Full name'),
  age: z.number().int().min(0).max(130),
  role: z.enum(['engineer', 'designer', 'manager']),
  skills: z.array(z.string()).max(5),
  nickname: z.string().optional(),
});

const person = await session.generateObject({ prompt: 'Extract: Priya, 31, a designer who knows Figma', schema: Person });
// person is typed as z.infer<typeof Person> and validated by Zod

Zod is not a dependency. Zod ≥ 4.2 implements Standard JSON Schema (~standard.jsonSchema), which this package reads directly. Other libraries implementing it work the same way.

With JSON Schema

import { jsonSchema } from '@fourlyn/apple-foundation-models';

const Sentiment = jsonSchema<{ label: 'positive' | 'neutral' | 'negative'; confidence: number }>({
  type: 'object',
  properties: {
    label: { type: 'string', enum: ['positive', 'neutral', 'negative'] },
    confidence: { type: 'number', minimum: 0, maximum: 1 },
  },
  required: ['label', 'confidence'],
});

const result = await session.generateObject({ prompt: 'I love it!', schema: Sentiment });

A plain JSON Schema object also works (the result is typed unknown).

Full response

const { object, usage, transcriptEntries, rawContent, isComplete } = await session.respondWithSchema({ prompt, schema });

rawContent is Apple’s GeneratedContent as JSON, before validation.

Options

generateObject / respondWithSchema / streamObject accept every respond option plus:

Option Default  
schemaName 'Response' Root schema name (appears in transcripts).
includeSchemaInPrompt true Also describe the schema in the prompt. Set false if instructions already explain the format (saves tokens).
validate true Run the Standard Schema validator (e.g. Zod refinements, transforms). Fails with SCHEMA_VALIDATION_FAILED.

Supported JSON Schema

Keyword Maps to
type: 'object', properties, required DynamicGenerationSchema(name:properties:); non-required ⇒ isOptional: true
type: 'array', items, minItems, maxItems DynamicGenerationSchema(arrayOf:minimumElements:maximumElements:)
type: 'string', pattern String + GenerationGuide.pattern(Regex)
enum / const (strings) DynamicGenerationSchema(name:anyOf: [String])
type: 'integer', minimum, maximum Int + .minimum / .maximum / .range
type: 'number', minimum, maximum Double + guides
type: 'boolean' Bool
type: 'null' (standalone) DynamicGenerationSchema.null (iOS 26.4)
['string', 'null'], anyOf: [X, {type:'null'}] optional property
anyOf / oneOf (several schemas) DynamicGenerationSchema(name:anyOf: [DynamicGenerationSchema])
$ref: '#/$defs/Name', $defs, definitions DynamicGenerationSchema(referenceTo:) + dependencies (recursive types OK)
description, title property / type descriptions and names

Ignored: additionalProperties, $schema, format, default, examples. Rejected with INVALID_SCHEMA: non-string enums, empty enums, invalid regex, unresolvable $ref.

Tips for good results