@xenterprises/fastify-x-ai
v1.3.0
Published
Fastify plugin for Vercel AI SDK - unified AI provider access with text generation, streaming, embeddings, and structured output
Readme
@xenterprises/fastify-x-ai
A Fastify plugin for the Vercel AI SDK providing unified access to AI providers (OpenAI, Anthropic, Google) with text generation, streaming, embeddings, and structured output. For teams that want one decorator (fastify.xAi) instead of wiring provider SDKs by hand.
Installation
npm install @xenterprises/fastify-x-ai fastify@5 ai
# Install the provider SDKs you actually use
npm install @ai-sdk/openai # OpenAI/GPT models
npm install @ai-sdk/anthropic # Anthropic/Claude models
npm install @ai-sdk/google # Google/Gemini modelsMinimal example
import Fastify from "fastify";
import xAI from "@xenterprises/fastify-x-ai";
const fastify = Fastify({ logger: true });
await fastify.register(xAI, {
providers: {
openai: { apiKey: process.env.OPENAI_API_KEY }, // the consumer owns env access
},
});
fastify.post("/complete", async (request) => {
const text = await fastify.xAi.complete(request.body.prompt);
return { text };
});Options
| Option | Type | Default | Required | Description |
|--------|------|---------|----------|-------------|
| active | boolean | true | No | Set false to skip registration entirely |
| defaultProvider | string | "openai" | No | Default provider: "openai", "anthropic", or "google" |
| defaultModel | string | Provider default | No | Default chat model (see defaults below) |
| defaultMaxTokens | number | 4096 | No | Default max output tokens (positive number) |
| defaultTemperature | number | 0.7 | No | Default temperature (0–2) |
| providers | object | {} | No | Provider configurations (see below) |
| providers.openai.apiKey | string | — | If providers.openai is set | OpenAI API key |
| providers.openai.baseURL | string | — | No | Custom base URL (OpenAI-compatible endpoints) |
| providers.anthropic.apiKey | string | — | If providers.anthropic is set | Anthropic API key |
| providers.anthropic.baseURL | string | — | No | Custom base URL (Anthropic-compatible endpoints) |
| providers.google.apiKey | string | — | If providers.google is set | Google API key |
| providers.google.baseURL | string | — | No | Custom base URL (Google-compatible endpoints) |
The plugin never reads process.env. Pass API keys in explicitly — a provider is
configured only when its providers.<name> entry is present, and each entry
requires an apiKey. If the matching provider SDK (@ai-sdk/openai,
@ai-sdk/anthropic, @ai-sdk/google) is not installed, registration logs a
warning and that provider is skipped.
Default chat models: OpenAI gpt-4o, Anthropic claude-sonnet-4-20250514,
Google gemini-2.0-flash. Default embedding models: OpenAI
text-embedding-3-small, Google text-embedding-004.
Decorators
All methods live on the single fastify.xAi namespace:
| Property | Signature | Description |
|----------|-----------|-------------|
| config | object | Resolved configuration (defaultProvider, defaultModel, defaultMaxTokens, defaultTemperature, providers — names of configured providers) |
| providers | object | Initialized provider client instances (created once at registration, reused) |
| generate(params) | Promise<object> | Generate text. Params: prompt or messages (one required), system, provider, model, maxTokens, temperature, tools, maxSteps, output. Returns { text, content, toolCalls, toolResults, finishReason, usage, totalUsage, steps, response, warnings } plus output when a structured output spec was passed |
| stream(params) | Promise<object> | Stream text. Same params as generate plus onChunk, onFinish, onError. Returns the AI SDK streamText result (use result.textStream) |
| chat(params) | Promise<object> | Conversation helper. messages required; stream: true delegates to stream(), otherwise to generate() |
| complete(prompt, options?) | Promise<string> | Simplest path — returns just the generated text |
| createEmbedding(params) | Promise<object> | text (single → { embedding, usage }) or texts (batch → { embeddings, usage }), plus provider, model |
| similarity(a, b) | number | Cosine similarity between two embeddings (-1 to 1) |
| generateStructured(params) | Promise<object> | prompt + schema (Zod or jsonSchema()) required; optional schemaName, schemaDescription. Result includes the parsed object at result.output |
| getModel(provider?, model?) | object | Resolve a language model instance (defaults applied) |
| raw | object | Raw AI SDK functions: generateText, streamText, embed, embedMany, cosineSimilarity |
No request decorators, no routes, no hooks.
Streaming to a client (SSE)
fastify.get("/stream", async (request, reply) => {
const result = await fastify.xAi.stream({ prompt: request.query.prompt });
reply.raw.writeHead(200, { "content-type": "text/event-stream" });
for await (const chunk of result.textStream) {
reply.raw.write(`data: ${JSON.stringify({ text: chunk })}\n\n`);
}
reply.raw.end("data: [DONE]\n\n");
});Structured output
import { z } from "zod";
const result = await fastify.xAi.generateStructured({
prompt: "Generate a recipe for chocolate cake",
schema: z.object({ name: z.string(), ingredients: z.array(z.string()) }),
schemaName: "Recipe",
});
console.log(result.output); // parsed objectError behavior
Registration fails fast with actionable Errors:
xai: option \defaultProvider` must be one of "openai", "anthropic", "google", e.g. ...`xai: option \defaultMaxTokens` must be a positive number, e.g. ...`xai: option \defaultTemperature` must be a number between 0 and 2, e.g. ...`xai: option \providers` must be an object, e.g. .../... has unknown provider "" ...`xai: missing required option \providers..apiKey` (string), e.g. ...`xai: 'ai' package is required. Install with: npm install ai
At call time:
xAI: Provider '<name>' not configured. Available: ...— provider used without a matchingprovidersentryxAI generate|stream: Either 'prompt' or 'messages' is requiredxAI chat: 'messages' is required/xAI complete: 'prompt' is requiredxAI createEmbedding: Either 'text' or 'texts' is requiredxAI generateStructured: 'prompt' is required/'schema' is required
Provider API errors (auth failures, rate limits, etc.) are AI SDK errors and propagate to the caller unchanged — use Fastify's error handling in routes.
Notes
- OpenAI models are pinned to the Chat Completions API (not the Responses API)
for consistent behavior across
@ai-sdk/openaiv1–v3. maxTokensis forwarded to both the AI SDK v4 (maxTokens) and v5+ (maxOutputTokens) parameter names, and structured output works on both (experimental_output/output), so the plugin behaves the same across the supportedaipeer range.
Requirements
- Node.js >= 20
- Fastify ^5.0.0 (peer dependency)
ai^4 || ^5 || ^6 (peer dependency), plus the provider SDKs you configure
License
SEE LICENSE IN LICENSE
