Integrations
TanStack AI
TanStack AI is a type-safe AI SDK from the TanStack team. Connect it to DEVUP AI with the openaiCompatible adapter.
Prerequisites
- Node.js
- A DEVUP AI API key from https://devupai.com/dashboard/api-keys.
Install
bash
npm install @tanstack/ai @tanstack/ai-openai zodThe examples use top-level await; save them in a .mts file. Node.js 24 runs .mts files directly: node app.mts.
Set your API key
export DEVUP_API_KEY="your-key"Create the adapter
openaiCompatible, from @tanstack/ai-openai/compatible, accepts any model ID you list in models.
typescript
import { chat } from "@tanstack/ai";
import { openaiCompatible } from "@tanstack/ai-openai/compatible";
const devupai = openaiCompatible({
name: "devupai",
baseURL: "https://api.devupai.com/v1",
apiKey: process.env.DEVUP_API_KEY ?? "",
models: ["deepseek-ai/DeepSeek-V4-Pro"],
});
const text = await chat({
adapter: devupai("deepseek-ai/DeepSeek-V4-Pro"),
messages: [{ role: "user", content: "Reply with exactly: Salam DEVUP" }],
stream: false,
});
console.log(text);Output: Salam DEVUP
Streaming
typescript
for await (const chunk of chat({
adapter: devupai("deepseek-ai/DeepSeek-V4-Pro"),
messages: [{ role: "user", content: "Count from 1 to 5, separated by spaces." }],
})) {
if (chunk.type === "TEXT_MESSAGE_CONTENT") process.stdout.write(chunk.delta);
}
console.log();Output: 1 2 3 4 5
Tool calling
Define a tool with toolDefinition, implement it with .server, and pass it in tools.
typescript
import { toolDefinition } from "@tanstack/ai";
import { z } from "zod";
const getOrderStatus = toolDefinition({
name: "getOrderStatus",
description: "Look up the delivery status of an order by its ID.",
inputSchema: z.object({ orderId: z.string() }),
}).server(async ({ orderId }) => ({ orderId, status: "shipped" }));
const toolCalls: string[] = [];
let answer = "";
for await (const chunk of chat({
adapter: devupai("deepseek-ai/DeepSeek-V4-Pro"),
messages: [{ role: "user", content: "What is the status of order A-100?" }],
tools: [getOrderStatus],
})) {
if (chunk.type === "TOOL_CALL_START") toolCalls.push(chunk.toolCallName);
if (chunk.type === "TEXT_MESSAGE_CONTENT") answer += chunk.delta;
}
console.log(toolCalls, answer);The agent calls getOrderStatus and answers that order A-100 has shipped.
Structured output
typescript
const city = await chat({
adapter: devupai("deepseek-ai/DeepSeek-V4-Pro"),
messages: [{ role: "user", content: "Which city is the capital of Algeria?" }],
outputSchema: z.object({
city: z.string().describe("Name of the capital city"),
country: z.string().describe("Country the city is in"),
}),
});
console.log(city);Output: { city: 'Algiers', country: 'Algeria' }
Choosing models
List exact catalog IDs in models and pass one to the adapter. Tool calling needs a model whose catalog entry supports it. See Models and Tool Calling.
Troubleshooting
- Authentication error (401)Set DEVUP_API_KEY in the same terminal that runs your script, without a Bearer prefix.
- Type error on the model nameThe standard OpenAI adapters only accept OpenAI model names. Use openaiCompatible from @tanstack/ai-openai/compatible and list your DEVUP AI model IDs in models.
- A structured field comes back as an identifierWith a JSON-schema response format, a field called name can be filled with an identifier instead of a value. Use a descriptive key such as city.