Real source · trimmed at build time

Seven ways into one toolkit

Follow the current implementation from host integration to the invariant underneath it. Every excerpt comes from the repository source during the build, with its original line numbers.

USE · INTERACTIVEAI SDK routepackages/agent-toolkit/examples/ai-sdk-route.ts

The smallest interactive host: authorize the principal, opt into writes, and give streamText() the registry projection plus the toolkit-owned system contract.

Highlighted lines carry the surface contract or lifecycle invariant.
/**
 * The whole AI SDK integration — a Next.js route handler.
 *
 * `auth0` is the zero-config singleton: it reads AUTH0_* env vars (live mode)
 * or falls back to an in-memory mock tenant with auto-approve (mock mode) so
 * this route works before a tenant exists. For explicit config — BYO stores,
 * custom tools, a signing key — swap in createAuth0Toolkit(config) from the
 * same subpath.
 */
import { auth0 } from '@auth0/agent-toolkit/ai-sdk';
import { convertToModelMessages, stepCountIs, streamText } from 'ai';

export const maxDuration = 300; // approvals block inside the tool call while CIBA polls

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: 'anthropic/claude-sonnet-5',
    // The lifecycle contract (plan first, never skip approval, report honestly)
    // is toolkit-owned — apps never hand-write it.
    system: auth0.systemPrompt(),
    // writes: true opts into the write tools; the user is who approvals route
    // to when APPROVER_MODE=session (the signed-in human's own phone).
    tools: auth0.tools({
      principal: {
        type: 'tenant-admin',
        user: { sub: 'auth0|the-host-authorized-admin' },
      },
      writes: true,
    }),
    stopWhen: stepCountIs(8),
    messages: await convertToModelMessages(messages),
  });

  return result.toUIMessageStreamResponse();
}