Skip to content

Vercel AI SDK

@ai-sdk/openai-compatible-এর createOpenAICompatible দিয়ে Vercel AI SDK-তে Tokens-কে provider হিসেবে বসান, তারপর generateText ও streamText চালান, Next.js route-সহ।

যেসব tool-এ কাজ করেVercel AI SDKNext.js

সর্বশেষ আপডেট 11 অক্টোবর 2026

Markdown-এ দেখুন
এই পাতায়

Vercel AI SDK Tokens-এর সাথে কথা বলে @ai-sdk/openai-compatible দিয়ে। এটা যেকোনো OpenAI-compatible API-র জন্য provider package। createOpenAICompatible দিয়ে provider একবার বানিয়ে নিন। এরপর generateText, streamText আর tool calling ঠিক সেভাবেই চলবে, যেভাবে first-party provider-গুলোতে চলে।

OpenCode ভেতরে এই একই package ব্যবহার করে। তাই ওখানে আপনি Tokens set up করে থাকলে (Tokens CLI এটা আপনার হয়ে করে দেয়), সবকিছু চেনা চেনা লাগবে।

Package install করুন#

bash
npm install ai @ai-sdk/openai-compatible zod
export TOKENS_API_KEY="tok_live_your_key"

উদাহরণগুলো AI SDK 7 (ai@7, @ai-sdk/openai-compatible@3) ধরে লেখা, যার জন্য Node.js 22 বা তার পরের version লাগে। AI SDK 5 বা 6-এ code একই থাকবে, শুধু system prompt দিতে হবে instructions-এর বদলে system দিয়ে।

createOpenAICompatible দিয়ে Tokens provider বানান#

lib/tokens.ts
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";

export const tokens = createOpenAICompatible({
  name: "tokens",
  baseURL: "https://tokens.bd/v1",
  apiKey: process.env.TOKENS_API_KEY,
  includeUsage: true, // ask for token counts on streamed responses
});

apiKey যায় Authorization: Bearer <key> হিসেবে। includeUsage: true দিলে streaming call-এ provider stream_options.include_usage set করে দেয়। এটা না থাকলে Tokens-এর stream-এ usage-এর কোনো তথ্য থাকে না, আর streamText call-এর পর usage ফাঁকা থেকে যায়।

Model-কে ডাকতে হয় তার Tokens ID দিয়ে: tokens("deepseek/deepseek-v4.1-flash")। ID নিজে টাইপ না করে /models বা GET /v1/models থেকে copy করুন।

generateText#

summarize.ts
import { generateText } from "ai";
import { tokens } from "./lib/tokens";

const { text, usage, finishReason } = await generateText({
  model: tokens("deepseek/deepseek-v4.1-flash"),
  instructions: "You summarize pull requests for busy reviewers.",
  prompt:
    "Summarize: refactored auth middleware to use a single session lookup; removed two duplicate DB calls.",
  maxOutputTokens: 300,
});

console.log(text);
console.log(finishReason, usage.inputTokens, usage.outputTokens);

streamText#

streamText-এ await দিতে হয় না। এটা সাথে সাথে ফেরত আসে, আর আপনি textStream পড়তে থাকেন।

stream.ts
import { streamText } from "ai";
import { tokens } from "./lib/tokens";

const result = streamText({
  model: tokens("deepseek/deepseek-v4.1-flash"),
  prompt: "Explain the difference between TCP and UDP for a junior developer.",
  maxOutputTokens: 600,
  onError: ({ error }) => console.error(error),
});

for await (const delta of result.textStream) {
  process.stdout.write(delta);
}

console.log("\n", await result.usage);

Stream চলার সময় যে error হয়, তা throw হয় না, আসে onError-এর মধ্য দিয়ে। তাই এটা অবশ্যই বসিয়ে নিন। নইলে 402 insufficient_credits শুধু একটা ফাঁকা response-এর মতো দেখাবে।

Next.js route handler থেকে stream করুন#

Tokens browser থেকে call করতে দেয় না (CORS header নেই), আর client code-এ আপনি key রাখতেও চান না। তাই streamText চালান একটা route handler-এ:

app/api/chat/route.ts
import { streamText } from "ai";
import { tokens } from "@/lib/tokens";

export async function POST(req: Request) {
  const { prompt } = (await req.json()) as { prompt?: string };
  if (!prompt) return Response.json({ error: "prompt required" }, { status: 400 });

  const result = streamText({
    model: tokens("deepseek/deepseek-v4.1-flash"),
    prompt,
    maxOutputTokens: 1024,
    abortSignal: req.signal,
  });

  return result.toTextStreamResponse();
}

toTextStreamResponse() সাধারণ text chunk পাঠায়, যা আপনি fetch আর একটা stream reader দিয়ে পড়তে পারবেন। আপনার frontend যদি @ai-sdk/react-এর useChat ব্যবহার করে, তাহলে prompt-এর বদলে request body থেকে messages নিন, সেগুলোকে convertToModelMessages দিয়ে বদলে নিন, আর ফেরত দিন result.toUIMessageStreamResponse()। Tokens-এর অংশ, মানে provider, বদলায় না।

Model আর output limit server-এ ঠিক করুন, যাতে visitor আপনার হয়ে দামি model বেছে নিতে না পারে। Route-এর সামনে authentication-ও বসান।

Tool calling#

যে model tool সাপোর্ট করে, তাতেই tool চলে। আগে /models-এ model-এর পেজটা দেখে নিন।

ts
import { generateText, tool, stepCountIs } from "ai";
import { z } from "zod";
import { tokens } from "./lib/tokens";

const { text, steps } = await generateText({
  model: tokens("deepseek/deepseek-v4.1-flash"),
  tools: {
    getWeather: tool({
      description: "Current weather for a city",
      inputSchema: z.object({ city: z.string() }),
      execute: async ({ city }) => ({ city, condition: "light rain", tempC: 29 }),
    }),
  },
  stopWhen: stepCountIs(3),
  prompt: "Do I need an umbrella in Dhaka right now?",
});

console.log(text, `(${steps.length} steps)`);

Model tool সাপোর্ট না করলে upstream provider request ফিরিয়ে দেয়, অথবা model tool-গুলো এড়িয়ে text-এ উত্তর দেয়। তখন এমন একটা model নিন যার তালিকায় tool সাপোর্ট লেখা আছে। Wire-level খুঁটিনাটি আছে Tool calling পেজে।

Error#

HTTP error আসে APICallError হিসেবে (ai থেকে export করা), যাতে থাকে statusCode, responseHeaders আর responseBody। Tokens-এর error code থাকে responseBody-র ভেতরে JSON হিসেবে, error.code-এর নিচে।

ts
import { APICallError, generateText } from "ai";
import { tokens } from "./lib/tokens";

try {
  await generateText({ model: tokens("deepseek/deepseek-v4.1-flash"), prompt: "hi" });
} catch (err) {
  if (APICallError.isInstance(err)) {
    console.error(err.statusCode, err.responseHeaders?.["x-tokens-request-id"], err.responseBody);
  }
}

AI SDK ব্যর্থ call default-এ দুইবার retry করে (maxRetries)। কিন্তু 429 window_exhausted retry করে ঠিক হয় না, কারণ plan window reset হলে তবেই সেটা কাটে। Code আর সমাধান আছে Errors ও Troubleshooting পেজে।

এই পাতাটা কি কাজে লেগেছে?

এখনো আটকে আছেন? Support ticket খুলুন

আপনার agent set up করতে সাহায্য লাগবে?

Connection tester দিয়ে সংযোগ পরীক্ষা করে নিন, অথবা একটা API key তৈরি করুন।