Skip to content

AI Builder

Generate forms from chat, then review the live result.

AI Builder turns a prompt into Formedible code, parses it locally, and shows the form beside the chat so teams can review it before shipping.

Public exports

Import AI builder pieces from the package root. It exports AIBuilder, parser pieces, provider helpers, TanStack AI adapters, storage helpers, and public types.

  • AIBuilder, ProviderSelection, ParserSettings, ChatInterface, and AiFormRenderer are root exports.
  • createDefaultProviderSettings, createDefaultProviderSecrets, providerOptions, and validateProviderAccess are exported from provider-selection.
  • createTanStackTextAdapter, DEFAULT_TANSTACK_AI_MODELS, and SUPPORTED_TANSTACK_AI_PROVIDERS are exported from ai-adapters.
  • Storage exports include readPersistedAIBuilderState, persistProviderSettings, persistProviderSecrets, persistConversations, exportConversation, and STORAGE_KEYS.

AIBuilder provider setup

AIBuilder can own provider state or accept controlled providerSettings and providerSecrets. It passes provider access, system prompt, parser config, messages, and form callbacks into ChatInterface.

  • mode defaults to client.
  • resolveInitialProviderAccess reads persisted settings, then chooses controlled secrets, stored secrets, or an empty key for the active provider.
  • Provider settings are persisted only when providerSettings is not controlled.
  • Provider secrets are persisted only when providerSecrets is not controlled.
  • The preview side renders AiFormRenderer only after formCode exists.
PropertyTypeDefaultDescription
mode
AIBuilderMode
'client'Only client mode is defined by AIBuilderMode.
providerSettings
ProviderSettings
Persisted/defaultOptional controlled provider, model, temperature, maxTokens, and Anthropic thinking budget.
providerSecrets
ProviderSecrets
Stored/emptyOptional controlled provider key object paired with the selected provider.
onFormGenerated
(formCode: string) => void
undefinedCalled when AIBuilder stores the latest generated form code.
onFormSubmit
(formData: FormedibleFormValues) => void | Promise<void>
undefinedPassed through to AiFormRenderer submit handling.

Provider and model lists

Provider support lives in providerOptions, ai-adapters, and the provider model catalog fetcher.

  • providerOptions contains openai, anthropic, and openrouter, all requiring keys.
  • DEFAULT_TANSTACK_AI_MODELS sets openai to gpt-5.4-mini, anthropic to claude-sonnet-4-6, and openrouter to minimax/minimax-m2.7.
  • createTanStackTextAdapter preserves custom model strings instead of falling back silently.
  • Model catalogs are fetched from provider APIs, cached locally, and refreshed on demand.
  • createTanStackModelOptions only returns Anthropic thinking options when thinkingBudgetTokens is positive.
ProviderDefault modelModel catalog source
openaigpt-5.4-miniGET https://api.openai.com/v1/models
anthropicclaude-sonnet-4-6GET https://api.anthropic.com/v1/models
openrouterminimax/minimax-m2.7GET https://openrouter.ai/api/v1/models?output_modalities=text

Provider validation and model options

Provider selection rejects mismatched secrets, unsupported providers, custom endpoints, non-Anthropic thinking budgets, and missing API keys.

  • createDefaultProviderSettings picks the selected provider option and copies its defaultModel.
  • validateProviderAccess requires settings and secrets to target the same provider.
  • endpoint and baseURL keys are rejected by both validateProviderAccess and assertNoUnsupportedRuntimeOptions.
  • thinkingBudgetTokens is accepted only for Anthropic provider settings.

Chat streaming and parser handoff

ChatInterface streams events into one assistant message. When the stream completes, it extracts a Formedible fence, parses it, stores parse errors on the message, and calls onFormGenerated.

  • Enter submits the prompt and Shift+Enter keeps the newline because the handler only submits when event.key is Enter and shiftKey is false.
  • streamAiResponse events are scheduled through createAiStreamScheduler before the assistant message is updated.
  • extractFormCode runs only when the final status is completed.
  • parseAiToFormedible writes formConfig on success and parseErrors on failure.

Parser integration and preview

AI Builder does not render generated text directly. parseAiToFormedible calls FormedibleParser.parseAiOutput, and AiFormRenderer passes parsed options into useFormedible.

  • parseAiToFormedible forwards strictValidation and allowed key/type lists into FormedibleParser.parseAiOutput.
  • inferDefaultValues fills booleans with false, number-like fields with 0, multiSelect/array with [], object/location with {}, and other fields with an empty string.
  • AiFormRenderer calls onParseComplete after reparsing non-streaming code.
  • Preview submits through the parsed onSubmit handler first, then through AIBuilder onFormSubmit.

Storage and export

AI Builder uses separate browser keys for provider settings, provider secrets, model catalogs, conversations, and UI state. Secret persistence can be memory, session, or local.

  • STORAGE_KEYS names five independent storage entries, including the cached provider model catalogs.
  • persistProviderSecrets clears both storage areas first; memory mode stores nothing.
  • rememberKey false stores the preference but not the secret value.
  • persistConversations writes sanitized conversations, and exportConversation returns a sanitized export envelope.

AI Builder shell path

AI generation returns the same field model used by hand-written forms.

import { useState } from 'react';

import { AIBuilder } from '@/components/ui/formedible/ai/ai-builder';
import { createDefaultProviderSecrets, createDefaultProviderSettings, ProviderSelection } from '@/components/ui/formedible/ai/provider-selection';

export function AiBuilderWorkspace() {
  const [providerSettings, setProviderSettings] = useState(() => createDefaultProviderSettings('openrouter'));
  const [providerSecrets, setProviderSecrets] = useState(() => createDefaultProviderSecrets('openrouter'));

  return (
    <main className="grid gap-8 lg:grid-cols-[22rem_1fr]">
      <ProviderSelection settings={providerSettings} secrets={providerSecrets} onChange={(settings, secrets) => {
        setProviderSettings(settings);
        setProviderSecrets(secrets);
      }} />
      <AIBuilder
        providerSettings={providerSettings}
        providerSecrets={providerSecrets}
        onProviderSettingsChange={setProviderSettings}
        onProviderSecretsChange={setProviderSecrets}
      />
    </main>
  );
}

Formedible

TanStack Form, shadcn/ui, Zod