npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@shivam.dixit/token-budget-vercel-ai

v0.1.5

Published

Vercel AI SDK adapter for token-budget: CoreMessage[] conversion, streaming integration, and an optional React hook — context window and token budget management for Vercel AI SDK agents.

Readme

token-budget-vercel-ai

Vercel AI SDK adapter for token-budget: CoreMessage[] conversion, streamText() streaming integration, and an optional React hook.

No dependency on the ai package — the types here are structurally compatible with its CoreMessage shapes, so either works without pulling the SDK in as a dependency.

Install

npm install @shivam.dixit/token-budget @shivam.dixit/token-budget-vercel-ai

token-budget is a peer dependency. react is an optional peer dependency, needed only for the token-budget-vercel-ai/react subpath.

Usage

import { TokenBudget } from '@shivam.dixit/token-budget';
import { toVercelMessages, fromVercelMessages, streamTextIntoBudget, reconcileUsage } from '@shivam.dixit/token-budget-vercel-ai';
import { streamText } from 'ai';

const budget = new TokenBudget({ maxTokens: 128000, reserve: 4096 });
budget.addMessage({ role: 'system', content: 'You are a helpful assistant.', pinned: true });
budget.addMessage({ role: 'user', content: 'What is the weather in Paris?' });

const ctx = await budget.getContext();
const result = streamText({ model, messages: toVercelMessages(ctx) });

// Pipes the stream's textStream into TokenBudget's streaming API
// (beginStream/appendStreamChunk/endStream) chunk by chunk, so
// stats().tokensUsed reflects partial output in real time.
const finalMessage = await streamTextIntoBudget(result.textStream, budget);

// Optional: compare against the SDK's own billed usage once available.
const usage = await result.usage;
console.log(reconcileUsage(finalMessage, usage));

React

import { useChat } from 'ai/react';
import { useTokenBudget } from '@shivam.dixit/token-budget-vercel-ai/react';

function Chat() {
  const { messages } = useChat();
  const { tokensUsed, tokensRemaining, isNearLimit } = useTokenBudget(messages, { maxTokens: 128000, reserve: 4096 });

  return (
    <div>
      {isNearLimit && <Banner>Approaching the context limit ({tokensUsed} used, {tokensRemaining} left)</Banner>}
      {/* ... */}
    </div>
  );
}

API

| Export | Description | | --- | --- | | toVercelMessages(context) | Converts a raw BudgetMessage[] or a getContext() result into CoreMessage[]. | | fromVercelMessages(messages) | Inverse: converts CoreMessage[] back into addMessage-ready input. | | streamTextIntoBudget(textStream, budget, options?) | Pipes a streamText() result's textStream into beginStream/appendStreamChunk/endStream, chunk by chunk. On an upstream error, finalizes the partial content (abortStream(id, 'keep-partial')) before rethrowing. | | reconcileUsage(message, usage) | Compares a finalized streamed message's token estimate against the SDK's onFinish usage, for logging — doesn't mutate the budget. | | useTokenBudget(messages, config) (from /react) | Reactive { tokensUsed, tokensRemaining, isNearLimit } derived from useChat()'s message list. |

Role mapping is direct: CoreMessage's roles (system/user/assistant/tool) match token-budget's exactly, unlike the Anthropic/OpenAI adapters. The system message stays inline (as with OpenAI), and tool stays tool (unlike Anthropic, which has no tool role on the wire).

Content & tool-call mapping

| token-budget ContentBlock.type | Vercel AI SDK part | | --- | --- | | text | { type: 'text', text } | | image ({ image, mimeType? }) | { type: 'image', image, mimeType } | | tool_call | { type: 'tool-call', toolCallId, toolName, args } | | tool_result | { type: 'tool-result', toolCallId, toolName, result, isError? } |

The wider project

Part of the token-budget monorepo — the core package, the other framework/tokenizer adapters, benchmarks, and the flagship coding-agent example all live there. See the compatibility matrix for exactly what every adapter is tested against.

License

MIT