Neutron AI
One SDK for model calls, streaming, structured output, and tools — over pluggable provider adapters. Swap OpenAI for Anthropic for any OpenAI-compatible endpoint by config, not by rewrite. Token accounting included.
Model calls, streaming, structured output, and tools — one SDK, any provider.
The model call, without the provider tax.
Every AI app pays the same tax: you wire directly to one vendor's SDK, hardcode its message shape, and then rewrite everything the day you want to switch. Neutron AI puts one interface in front of both wire protocols — the OpenAI Chat Completions format and the Anthropic Messages format. You call generateText, streamText, generateObject, and streamObject; the adapter underneath is a config detail. Point baseURL at any OpenAI-compatible server — Groq, DeepSeek, vLLM, Ollama, an AI gateway — and the same code runs unchanged.
It's not a toy. Neutron AI is the model gateway behind Teploy Ship in production — the layer that turns an issue into a pull request runs every model call through this SDK.
import { generateText } from "@neutron-build/ai";
import { anthropic } from "@neutron-build/ai/anthropic";
// import { openai } from "@neutron-build/ai/openai"; // same call, other provider
const { text, usage } = await generateText({
model: anthropic("claude-sonnet-4-5"),
system: "You write tight, factual release notes.",
prompt: "Summarize this diff in three bullets:\n" + diff,
});
console.log(text);
console.log(usage.inputTokens, usage.outputTokens); // accounted per callModelAdapter interface. Swap providers by changing the model argument — the call site never moves.baseURL, so Groq, DeepSeek, vLLM, Ollama, and gateways all work through the same code. Vendor is a config line.streamText gives you a textStream of deltas and a fullStream of typed parts. Awaitable text, usage, and messages settle when it's done.generateObject returns a schema-validated object via a forced tool call — the one mechanism every provider supports identically, so results are portable across adapters.tool with a schema and an execute, set maxSteps, and the SDK runs the model-call-then-tool loop for you. Client-side and approval-gated tools too.Usage with input and output tokens, summed across steps. Meter, bill, and budget without bolting on a second SDK.Structured output that actually validates.
Ask for JSON and most SDKs hand you a string and a prayer. generateObject forces the model through a tool call shaped by your schema, then validates the result before it reaches you — typed all the way out.
import { generateObject, jsonSchema } from "@neutron-build/ai";
import { openai } from "@neutron-build/ai/openai";
const Ticket = jsonSchema<{ severity: "low" | "high"; area: string }>({
type: "object",
properties: {
severity: { type: "string", enum: ["low", "high"] },
area: { type: "string" },
},
required: ["severity", "area"],
});
const { object } = await generateObject({
model: openai("gpt-4o-mini"),
schema: Ticket,
prompt: "Triage: 'the deploy step hangs on every push to main'",
});
route(object.severity, object.area); // object is typed and validatedTools the model can actually call.
A tool is a schema plus a function. Hand the SDK a set of them and a step budget, and it runs the loop — call the model, execute the tools it asked for, feed the results back, repeat — until the model is done or the budget runs out.
import { generateText, tool, jsonSchema } from "@neutron-build/ai";
import { anthropic } from "@neutron-build/ai/anthropic";
const search = tool({
name: "search_docs",
description: "Find relevant docs for a query.",
inputSchema: jsonSchema<{ query: string }>({
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
}),
execute: async ({ query }) => db.vector("docs").search(query).k(5),
});
const { text, steps } = await generateText({
model: anthropic("claude-sonnet-4-5"),
tools: [search],
maxSteps: 6,
prompt: "How do I configure the scheduler?",
});What it's for
Chat and assistant features that stream tokens to the UI. Extraction and classification pipelines that need typed, validated output. Tool-using agents that call your database and your APIs. Embedding and semantic-search flows through embed and embedAndStore. Anywhere you'd reach for a vendor SDK but don't want to marry the vendor.
Why one SDK over every provider?
Because model choice is a moving target and vendor lock-in is a liability, not a feature. The wire protocols are stable; the models behind them change monthly. Program against the interface, and switching a model — or A/B testing two — is a one-line diff. Structured output goes through forced tool calls precisely so it behaves the same on a frontier model and a self-hosted one.
Part of a bigger system
Neutron AI is the foundation the rest of the agent stack builds on. Neutron Agents composes this SDK with the Workflow SDK to make durable, file-based agents. Neutron Workflow makes any tool loop survivable across restarts. Same contract, same errors (RFC 7807), same Nucleus database underneath.