UNPKG

@juspay/neurolink

Version:

The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002

104 lines (103 loc) • 4.43 kB
/** * Token Estimation Utilities * * Provides character-based token estimation with per-provider adjustment * multipliers. Uses the same approach as Continue (gpt-tokenizer baseline * + provider multipliers) but without requiring a tokenizer dependency. * * Multiplier sources: Continue project's getAdjustedTokenCount.ts * - Anthropic: 1.23x (Anthropic tokenizer produces ~23% more tokens) * - Google (AI Studio / Vertex): 1.18x * - Mistral/Codestral: 1.26x * - OpenAI/GPT: 1.0x (baseline) */ import type { ChatMessage } from "../types/index.js"; /** Characters per token for English text */ export declare const CHARS_PER_TOKEN = 4; /** Characters per token for code */ export declare const CODE_CHARS_PER_TOKEN = 3; /** * Safety margin: additive fraction of baseTokens added to the provider-adjusted estimate. * Using additive margin prevents compounding with provider multipliers. * * Old behavior: baseTokens * providerMultiplier * 1.15 (compounding) * e.g. Anthropic: baseTokens * 1.23 * 1.15 = baseTokens * 1.4145 * New behavior: baseTokens * providerMultiplier + baseTokens * 0.05 (additive) * e.g. Anthropic: baseTokens * 1.23 + baseTokens * 0.05 = baseTokens * 1.28 */ export declare const TOKEN_SAFETY_MARGIN_ADDITIVE = 0.05; /** @deprecated Use TOKEN_SAFETY_MARGIN_ADDITIVE instead. Kept for backward compatibility. */ export declare const TOKEN_SAFETY_MARGIN = 1.15; /** Message framing overhead in tokens (role + delimiters) */ export declare const TOKENS_PER_MESSAGE = 4; /** Conversation-level overhead in tokens */ export declare const TOKENS_PER_CONVERSATION = 24; /** Image token estimate (flat) */ export declare const IMAGE_TOKEN_ESTIMATE = 1024; /** * Get the token multiplier for a given provider. */ export declare function getProviderMultiplier(provider?: string): number; /** * Estimate token count for a string. * * @param text - Input text * @param provider - Optional provider for multiplier adjustment * @param isCode - Whether the text is code (uses CODE_CHARS_PER_TOKEN) * @returns Estimated token count */ export declare function estimateTokens(text: string, provider?: string, isCode?: boolean): number; /** * Serialize an arbitrary value for estimation. Never throws: `JSON.stringify` * raises RangeError once a value exceeds V8's max string length, and a tool * argument blob is exactly the shape that gets there. A payload that large is * charged at the fallback size rather than aborting the estimate (and with it * the whole turn). */ /** * Serialize a value for token estimation. The fallback is deliberately huge: * an estimator that cannot measure a value must over-report, so a budget guard * fires rather than waving through content it failed to size. */ export declare function serializeForEstimate(value: unknown): string; /** * Estimate token count for a single ChatMessage. * Includes message framing overhead. * * Counts `content` AND `args`. A `tool_call` is persisted with an EMPTY * `content` and its entire payload in `args` (see flushPendingToolData), * so a content-only estimate scored a 39 KB Write call at ~28 tokens against a * real cost near 9,750 — the budget checker, the compaction trigger and the * summarization threshold were all blind to the single largest source of * context growth in an agentic session. * * `result` is deliberately NOT counted: `result.result` is re-hydrated FROM * `content` at read time (redisConversationMemoryManager), so counting both * double-bills the same bytes. Only `result.error`, which has no counterpart in * `content`, is included. */ export declare function estimateMessageTokens(message: ChatMessage | { role: string; content: unknown; }, provider?: string): number; /** * Estimate total token count for an array of messages. * Includes conversation-level overhead. */ export declare function estimateMessagesTokens(messages: Array<ChatMessage | { role: string; content: unknown; }>, provider?: string): number; /** * Truncate text to fit within a token budget. * Tries to cut at sentence or word boundaries. * * @param text - Input text * @param maxTokens - Maximum tokens allowed * @param provider - Optional provider for multiplier * @returns Truncated text with "..." suffix if truncated */ export declare function truncateToTokenBudget(text: string, maxTokens: number, provider?: string): { text: string; truncated: boolean; };