The community AI SDK provider for Interfaze — an LLM built for developers and automations.
Docs · limits · pricing · dashboard · TypeScript SDK · Python SDK
It brings Interfaze to the standard generateText / streamText / generateObject surface, and surfaces Interfaze's extras — the semantic-cache flag, reasoning, and internal-task precontext — on providerMetadata.
Community provider, maintained by Interfaze. For the list of first-party providers see the AI SDK docs; for community providers, the community list.
npm install @interfaze-ai/ai-sdk
# or: yarn add · pnpm add · bun add @interfaze-ai/ai-sdkSet INTERFAZE_API_KEY in your environment (or pass apiKey to createInterfaze). Get a key from the Interfaze dashboard.
Import the default interfaze instance, or build one with createInterfaze:
import { createInterfaze, interfaze } from '@interfaze-ai/ai-sdk';
interfaze('interfaze-beta'); // default, reads INTERFAZE_API_KEY
const custom = createInterfaze({ apiKey: 'sk_...' });Drop an image into the prompt and get a typed object back — Interfaze runs OCR under the hood and hands you both the structured result and the raw OCR that produced it:
import { interfaze } from '@interfaze-ai/ai-sdk';
import { generateObject } from 'ai';
import { z } from 'zod';
const { object, providerMetadata } = await generateObject({
model: interfaze('interfaze-beta'),
schema: z.object({
first_name: z.string(),
last_name: z.string(),
dob: z.string().describe('Date of birth on the ID'),
licence_number: z.string(),
}),
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Extract the details from this ID.' },
{
type: 'image',
image: new URL(
'https://r2public.jigsawstack.com/interfaze/examples/id.jpg',
),
},
],
},
],
});
console.log(object); // { first_name, last_name, dob, licence_number }
console.log('OCR result:', providerMetadata?.interfaze?.precontext?.[0]); // the raw OCRAlongside the answer, a response carries precontext — the raw output of any internal tool Interfaze ran while answering (OCR, web search, scrape, transcription, …). It lands on providerMetadata.interfaze.precontext:
const { text, providerMetadata } = await generateText({
model: interfaze('interfaze-beta'),
prompt: 'Which US public companies reported earnings today?',
});
for (const p of providerMetadata?.interfaze?.precontext ?? []) {
console.log(p); // e.g. { name: "search", result: { … } }
}Precontext is output-only — it reports what Interfaze did while answering. There is no way to feed it back in.
import { interfaze } from '@interfaze-ai/ai-sdk';
import { generateText } from 'ai';
const { text } = await generateText({
model: interfaze('interfaze-beta'),
prompt: 'Which US public companies reported earnings today?',
});A web search backs the answer here — the sources land on providerMetadata.interfaze.precontext.
streamText streams the reply as it's generated; the inline <think> / <precontext> side-channels are stripped from the visible text, and reasoning is attached to providerMetadata when the stream finishes. Streamed precontext is only emitted when the provider is created with showAdditionalInfo: true (see Client options); otherwise it's undefined at finish.
const interfaze = createInterfaze({ showAdditionalInfo: true }); // for streamed precontext
const { textStream, providerMetadata } = streamText({
model: interfaze('interfaze-beta'),
prompt: "Summarize this week's top AI research and cite your sources.",
});
for await (const delta of textStream) process.stdout.write(delta);
const meta = await providerMetadata; // meta?.interfaze?.reasoning; .precontext when showAdditionalInfo is setInterfaze supports structured outputs, so generateObject / streamObject work with a Zod schema:
import { interfaze } from '@interfaze-ai/ai-sdk';
import { generateObject } from 'ai';
import { z } from 'zod';
const { object } = await generateObject({
model: interfaze('interfaze-beta'),
schema: z.object({
merchant: z.string(),
total: z.number(),
items: z.array(z.object({ name: z.string(), price: z.number() })),
}),
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Extract this receipt.' },
{
type: 'image',
image: new URL('https://jigsawstack.com/preview/vocr-example.jpg'),
},
],
},
],
});Interfaze supports tools — define them and the AI SDK runs the usual tool loop:
import { interfaze } from '@interfaze-ai/ai-sdk';
import { generateText, tool } from 'ai';
import { z } from 'zod';
const { text, toolResults } = await generateText({
model: interfaze('interfaze-beta'),
tools: {
weather: tool({
description: 'Get the current weather for a location',
inputSchema: z.object({ location: z.string() }),
execute: async ({ location }) => ({ location, temperatureF: 72 }),
}),
},
prompt: 'Use the weather tool to get the weather in San Francisco.',
});Interfaze routes requests through a mixture-of-agents router that decides whether to call a user tool or answer directly from its own live data, so
tool_choiceis advisory. Give an explicit instruction when you need a specific tool invoked.
Set reasoningEffort ('minimal' | 'low' | 'medium' | 'high', plus Interfaze's 'on' | 'off' | 'auto'); the reasoning text comes back on providerMetadata.interfaze.reasoning:
const { text, providerMetadata } = await generateText({
model: interfaze('interfaze-beta'),
prompt: 'Which region should we launch in first, and why?',
providerOptions: { interfaze: { reasoningEffort: 'high' } },
});
providerMetadata?.interfaze?.reasoning; // string | undefinedA semantic-cache hit replays a stored answer without reasoning — set bypassCache: true on the provider (see Client options) when you need fresh reasoning every call.
Images, audio, video and documents all use standard AI SDK content parts. Pass a public URL — Interfaze fetches it server-side, so nothing is downloaded and re-encoded on the way out — or raw bytes:
Supported media types:
| Kind | Types |
|---|---|
| Image | image/jpeg image/png image/webp image/bmp image/heic image/heif |
| Audio | audio/wav audio/mpeg audio/mp4 audio/ogg audio/flac |
| Video | video/mp4 video/quicktime video/webm video/3gpp video/x-msvideo video/x-matroska |
| Documents | application/pdf, .docx, application/json application/xml application/yaml |
| Text | text/plain text/csv text/markdown text/tab-separated-values |
image/gif and image/avif are rejected by the API.
await generateText({
model: interfaze('interfaze-beta'),
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Summarize this document.' },
{
type: 'file',
mediaType: 'application/pdf',
data: new URL('https://arxiv.org/pdf/1706.03762'),
},
],
},
],
});Video is a file part with a video/* media type; Interfaze reads the URL server-side:
{ type: "file", mediaType: "video/mp4", data: new URL("https://…/clip.mp4") }Enable safety categories with guard; a blocked request comes back as a normal completion whose text is the plain string unsafe <code> (not an error), so check for it:
const { text } = await generateText({
model: interfaze('interfaze-beta'),
prompt: '...',
providerOptions: { interfaze: { guard: ['S1', 'S10', 'S12_IMAGE'] } },
});
if (text.startsWith('unsafe ')) {
// blocked — text is e.g. "unsafe S1"
}Codes are S1–S14, the image-only S1_IMAGE / S12_IMAGE / S15_IMAGE, and ALL (enables everything).
Interfaze returns fields a plain chat provider drops. They land on providerMetadata.interfaze for both generateText and streamText:
const result = await generateText({
model: interfaze('interfaze-beta'),
prompt: 'What is the weather in San Francisco?',
});
result.providerMetadata?.interfaze?.vcache; // boolean — semantic-cache hit
result.providerMetadata?.interfaze?.reasoning; // string | undefined
result.providerMetadata?.interfaze?.precontext; // unknown[] | undefined — OCR / web / scrape / … outputRouter, cache, and streaming behavior are set once on the provider:
const interfaze = createInterfaze({
showAdditionalInfo: true, // stream <precontext> deltas as they're produced
bypassMoA: true, // skip the mixture-of-agents router
bypassCache: true, // skip the semantic cache
});Zero data retention (ZDR) is configured at the account/infrastructure level, not via a per-request flag or client header — contact Interfaze to enable it for your account.
Interfaze errors surface as the AI SDK's APICallError, carrying the HTTP status and response body:
import { APICallError } from 'ai';
try {
await generateText({ model: interfaze('interfaze-beta'), prompt: '...' });
} catch (error) {
if (APICallError.isInstance(error)) {
error.statusCode; // e.g. 400, 401, 429
error.responseBody; // raw Interfaze error payload
}
}| Use case | Entry point |
|---|---|
| Text | generateText |
| Streaming | streamText |
| Structured output | generateObject / streamObject |
| Tools | tools |
| Reasoning | providerOptions.interfaze.reasoningEffort |
| Multimodal | image / file content parts |
| Guardrails | providerOptions.interfaze.guard |
| Precontext | providerMetadata.interfaze.precontext |
| Semantic cache | providerMetadata.interfaze.vcache |
Runnable snippets in examples/ — one per feature (quickstart, streaming, structured output, tools, reasoning, guardrails, multimodal, precontext, errors). Set INTERFAZE_API_KEY, then npx tsx examples/quickstart.ts.
MIT