TypeSafe

Use TypeSafe System One models for typed decisions with the AI SDK.

The TypeSafe provider supports the experimental decision API with native Choice, Score, and Boolean answers. It sends all questions in one request against the same state.

Setup

Install the provider:

pnpm add @ai-sdk/typesafe-ai

Set the TYPESAFE_AI_API_KEY environment variable. Import the default provider or configure an instance:

import { createTypeSafeAi, typeSafeAi } from '@ai-sdk/typesafe-ai';

const customTypeSafe = createTypeSafeAi({
  apiKey: 'your-api-key',
});

createTypeSafeAi accepts:

SettingDescription
apiKeyAPI key; defaults to TYPESAFE_AI_API_KEY.
baseURLDefaults to TYPESAFE_AI_BASE_URL, then https://api.typesafe.ai/v1.
headersAdditional request headers.
fetchCustom fetch implementation.

Use TYPESAFE_AI_BASE_URL to route the default typeSafeAi instance through a trusted proxy or self-hosted TypeSafe-compatible server:

TYPESAFE_AI_BASE_URL=http://127.0.0.1:8766/v1

An explicit baseURL passed to createTypeSafeAi takes precedence over the environment variable. The configured server receives the API key and decision state and must implement the TypeSafe POST /systemone API.

Decision

import { typeSafeAi } from '@ai-sdk/typesafe-ai';
import { experimental_decide } from 'ai';

const result = await experimental_decide({
  model: typeSafeAi.decisionModel('jev-latest'),
  state: {
    message: 'I was charged twice. Please refund the duplicate.',
  },
  questions: {
    department: {
      type: 'choice',
      instructions: 'Which team should handle this?',
      criteria: {
        billing: { includes: ['Charges', 'Invoices', 'Refunds'] },
        technical: ['Bugs', 'Outages'],
        other: null,
      },
    },
    severity: {
      type: 'score',
      instructions: 'How severe is the issue?',
      criteria: ['Cosmetic', 'Workaround exists', 'Blocking; no workaround'],
    },
    requestsRefund: {
      type: 'boolean',
      instructions: 'Is the customer requesting money back?',
    },
  },
});

console.log(result.answers.department.choice);
console.log(result.answers.severity.score);
console.log(result.answers.requestsRefund.probability);
console.log(result.usage);

Use jev-latest or another TypeSafe model ID. The response includes the actual model ID, such as the resolved version behind the alias. Use model instances, custom aliases, or registered providers. With typeSafeAi explicitly configured as globalThis.AI_SDK_DEFAULT_PROVIDER, you can pass model: 'jev-latest' directly. See model aliases and registries.

QuestionNative TypeSafe primitiveLimits and semantics
choiceChoice1–255 options; selected option and full probabilities.
scoreScore2–10 ordered rubric levels; fractional score and full probabilities.
booleanNoulRequired model-estimated probability of true.

State, instructions, and descriptions accept JSON objects and arrays in addition to strings. Descriptions may be null. Boolean true/false criteria are optional. The SDK uses the neutral name boolean and maps it to TypeSafe's noul field.

Rounded values and confidence

TypeSafe returns scores and probabilities rounded to two decimal places. result.rounding reports this precision so the SDK can account for rounding when checking distribution sums and weighted means. The returned values are preserved unchanged; rounding means probabilities may not add up to exactly one.

Confidence is a separate TypeSafe statistic, available under result.providerMetadata.typesafe.confidence[questionId] for Choice and Score answers. Boolean probability always means P(true), not confidence in either outcome. Choose decision thresholds in application code.

Errors and retries

Provider failures use APICallError, including validation and authentication errors. Core retries transient failures such as 429 and 529 according to maxRetries (default: 2). abortSignal, request headers, and custom fetch are forwarded. There is no provider-side retry loop.

No provider-specific options are currently defined. Unknown entries under providerOptions.typesafe produce unsupported-option warnings. Language, embedding, and image model factories throw NoSuchModelError.

Decision models support workflow serialization. A custom fetch function is not serialized; restored models use the default fetch implementation.