- OpenAIUpdated
- OpenAI: AdvancedNew
- AnthropicUpdated
- Anthropic: AdvancedNew
- Google GeminiUpdated
- Google Gemini: AdvancedNew
- Google Vertex AIUpdated
- OllamaUpdated
- Grok (xAI)Updated
- GroqUpdated
- MistralUpdated
- CohereUpdated
- TypeSafeUpdated
- OllayaUpdated
- ElevenLabsUpdated
- fal.aiUpdated
- ReactorUpdated
- World LabsUpdated
- OpenRouter AdapterUpdated
- OpenRouter: AdvancedNew
- Perplexity SearchUpdated
- Vercel AI GatewayUpdated
- Lovable AI GatewayUpdated
- OpenAI-CompatibleUpdated
- OpenAI-Compatible: AdvancedNew
- LLM GatewayUpdated
- CloudflareUpdated
- Claude CodeUpdated
- CodexUpdated
- OpenCodeUpdated
- Grok BuildUpdated
- ACP-CompatibleUpdated
- Amazon BedrockUpdated
- BytePlusUpdated
- BytePlus: AdvancedNew
TypeSafe
The TypeSafe adapter calls Jev through decide(). Jev returns a typed answer about your data. The adapter has no chat.
1. Install#
npm i @tanstack/ai @tanstack/ai-typesafepnpm add @tanstack/ai @tanstack/ai-typesafeyarn add @tanstack/ai @tanstack/ai-typesafebun add @tanstack/ai @tanstack/ai-typesafe2. Set the API key#
Get a key from TypeSafe. Put it in the environment of your server:
TYPESAFE_API_KEY=your-typesafe-api-keytypesafeDecider reads TYPESAFE_API_KEY. To pass the key in code, use createTypesafeDecider:
import { createTypesafeDecider } from "@tanstack/ai-typesafe";
const adapter = createTypesafeDecider("jev-latest", process.env.MY_TYPESAFE_KEY!);3. Ask your first questions from the server#
This route reads a support ticket and asks Jev three questions about it:
import { decide, choice, score, boolean } from "@tanstack/ai";
import { typesafeDecider } from "@tanstack/ai-typesafe";
export async function POST(request: Request) {
const ticket = await request.text();
const result = await decide({
adapter: typesafeDecider("jev-latest"),
state: ticket,
questions: {
queue: choice({
instructions: "Which team should handle this ticket?",
options: {
billing: "Payments, invoices, refunds",
tech: "Bugs, outages, integrations",
sales: "Pricing, upgrades, new accounts",
},
}),
urgency: score({
instructions: "How urgent is this ticket?",
levels: ["low", "medium", "high"],
}),
refund: boolean({
instructions: "Is the customer asking for a refund?",
}),
},
});
return Response.json({
queue: result.queue.value,
urgency: result.urgency.value,
refund: result.refund.value,
});
}Each answer also has a probability. result.meta.usage has the token count.
4. Call the route from the client#
decide() needs your API key, so it stays on the server. The client sends the ticket text to the route:
export async function evaluateTicket(ticket: string) {
const response = await fetch("/api/evaluate", {
method: "POST",
body: ticket,
});
return response.json();
}Call evaluateTicket("Charged twice for the same invoice. Please refund the extra payment.") and you get back something like { queue: "billing", urgency: "medium", refund: true }.
For the question helpers, the result shape, abort, and middleware, see Evaluate. For a full TanStack Start app, see Evaluate a ticket.
Models and options#
| Model | Description |
|---|---|
| jev-latest | The current stable Jev release |
| jev-1.13.0 | A pinned Jev release |
You can also pass other TypeSafe model ids as a string. The package exports the known ids as TYPESAFE_EVALUATE_MODELS.
Advanced#
Behind a proxy#
To send every request through a gateway, set baseURL and defaultHeaders. All TanStack AI adapters use these two option names:
import { createTypesafeDecider } from "@tanstack/ai-typesafe";
const adapter = createTypesafeDecider("jev-latest", process.env.TYPESAFE_API_KEY!, {
baseURL: "https://gateway.example.com/typesafe",
defaultHeaders: {
"cf-aig-authorization": `Bearer ${process.env.GATEWAY_TOKEN}`,
},
});baseUrl and headers are aliases of the same two options. If you set both forms, baseURL and defaultHeaders win.
Bring your own key#
typesafeByok from @tanstack/ai-typesafe/byok declares TypeSafe for the BYOK store, with TYPESAFE_API_KEY as its env var. See Bring Your Own Key.
API reference#
The adapter sends POST /v1/systemone to the base URL with fetch. There is no TypeSafe SDK.
| Factory | Creates |
|---|---|
| typesafeDecider(model, config?) | An evaluate adapter. Reads TYPESAFE_API_KEY. |
| createTypesafeDecider(model, apiKey, config?) | The same adapter with an explicit API key. |
The config fields:
- baseURL: the API base URL. The default is https://api.typesafe.ai. baseUrl is an alias.
- defaultHeaders: extra request headers. headers is an alias.
- fetch: your own fetch function.