AI Object Reference
Use useAIObject for generated or extracted content that decisions cannot express: titles, lists, nested fields, and prose inside a schema. For a yes/no, one category from a fixed set, or a position on an ordered rubric, use useAIDecisions. Decisions are far cheaper and faster, and the probability can drive the interface.
A feature can use both. Generate the content here, and judge priority, intent, or urgency with decide(). Do not put a boolean, a fixed category, or a rubric score in an object schema. generateObject does not stream partial objects, and it resolves to undefined instead of throwing when a request fails.
useAIObject
Returns
generateObject(function): Generate structured data.isLoading(boolean): Whether a request is in progress.error(Error | null): Current error.clearError(() => void): Clear the current error.
generateObject Input
prompt(string, required): Description of the object to generate.schema(object, required): JSON Schema for the output. Convert a Zod schema withz.toJSONSchema(...)before passing it. The hook does not accept a Zod object directly.systemPrompt(string): Instruction that guides the AI.enableWebSearch(boolean): Allow the AI to search for current information.context(object): Additional JSON-serializable context.attachments(FileList,File[], or an array of file or URL objects): Images, PDFs, audio, video, or YouTube URLs.model(string): Model ID for the request.reasoningEffort("minimal","low","medium", or"high"): Reasoning depth for the request.
generateObject resolves to the generated object on success or undefined on failure. It never rejects.
Schema rules
Schemas must follow the structured-output subset:
- The root type must be
"object". - Every object must set
"additionalProperties": false. - Every property must be listed in
required; optional fields are not supported. - Supported types are
"string","number","integer","boolean","object", and"array". enumvalues must be strings. A quantity uses"number"with a description. A fixed category or ordered score is a decision, not an enum or number in this schema.- Keep schemas to
type,properties,items,required,enum,default,description, andadditionalProperties.
Example
import { useAIObject } from '@/hooks/use-ai'
import { usePersistentItem } from '@/hooks/use-persistent-item'
type Plan = {
title: string
summary: string
tasks: string[]
}
export default function App() {
const [plan, setPlan] = usePersistentItem<Plan | null>('plan', null)
const { generateObject, isLoading, error } = useAIObject()
const handleGeneratePlan = async (goal: string) => {
const result = await generateObject<Plan>({
prompt: `Generate a plan for: ${goal}`,
schema: {
type: 'object',
properties: {
title: { type: 'string' },
summary: { type: 'string' },
tasks: { type: 'array', items: { type: 'string' } },
},
required: ['title', 'summary', 'tasks'],
additionalProperties: false,
},
})
if (result) setPlan(result)
}
return (
<div>
{isLoading ? <p>Generating...</p> : null}
{error ? <p className="text-destructive">{error.message}</p> : null}
{plan ? <pre>{JSON.stringify(plan, null, 2)}</pre> : null}
</div>
)
}
Judge urgency or priority of that plan with useAIDecisions, not with another field in this schema.
Attachments and Web Search
generateObject accepts attachments in per-request options. Use files directly from local inputs, uploaded file URLs, or YouTube URLs:
const { generateObject } = useAIObject()
await generateObject({
prompt: 'Extract the receipt details',
schema: receiptSchema,
attachments: [receiptImageFile],
})
await generateObject({
prompt: 'Extract the main topics discussed',
schema: topicsSchema,
attachments: [{ url: youtubeUrl }],
})
Set enableWebSearch: true for prompts that need current information, such as weather, news, or live facts. Describe how each file or URL should map onto schema properties.
Reasoning Effort
Use reasoningEffort to trade latency for reasoning depth on generateObject:
"minimal": Fastest, with the least reasoning."low": Light reasoning."medium": Balanced reasoning."high": Maximum reasoning depth.
If omitted, the platform uses its default. Classification, yes/no judgments, and rubric scores belong on decisions, which do not use reasoning effort.
Model Selection
When no model is specified, the platform chooses an efficient default model for the user's plan. useAIObject uses text models. To expose model choice, pass a model ID and build selectors from listTextModels():
import { listTextModels, useAIObject } from '@/hooks/use-ai'
const models = listTextModels()
const [modelId, setModelId] = React.useState<string | undefined>(undefined)
const { generateObject } = useAIObject()
await generateObject({
prompt: 'Generate a weeknight pasta recipe',
schema: recipeSchema,
model: modelId,
})
listTextModels() returns an array of model objects with:
id: Model ID to pass asmodel.displayName: Human-readable display name.provider: Provider name.tier:"lite","standard", or"advanced".description: Short model description.capabilities: Capability strings such asweb_search,image_input,file_input,audio_input, andvideo_input.
Lite models are available on every plan. Standard models require Basic or Pro. Advanced models require Pro. More capable models cost more credits. Deprecated models automatically fall back to a recommended replacement.
Best Practices
- Use
generateObject's promise result and store it withusePersistentItemor React state. - Keep schemas small and explicit, and include
additionalProperties: falseon every object. - List every property in
required. The schema does not support optional fields. - Include clear instructions when using attachments so the model knows how to use each file or URL.
- Send a yes/no, a fixed category, or a rubric score through
useAIDecisions.