DEVUP Docs
Back to Dashboard

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

Install

bash
npm install @tanstack/ai @tanstack/ai-openai zod

The 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.