/** * Type definitions for the BPE tokenizer. */ /** * OpenAI encoding types. */ type OpenAIEncoding = 'r50k_base' | 'p50k_base' | 'p50k_edit' | 'cl100k_base' | 'o200k_base' | 'o200k_harmony'; /** * How special tokens are handled during encoding. */ type SpecialTokenHandling = /** Allow special tokens and encode them as special token IDs */ 'all' /** Treat special tokens as regular text */ | 'none' /** Throw error if special token strings appear (default) */ | 'none_raise'; /** * OpenAI BPE tokenization API. * * Provides encode/decode functions for OpenAI models using our native * BPE implementation (tiktoken-compatible). */ interface EncodeOptions { /** * Explicit OpenAI encoding override. * When provided, this takes precedence over `model`. */ encoding?: OpenAIEncoding; /** * OpenAI model ID used to select the appropriate encoding. */ model?: string; /** * How special tokens are handled. * - `none_raise` (default): throw if special tokens appear * - `none`: treat special tokens as regular text * - `all`: allow special tokens and encode them as special token IDs */ allowSpecial?: SpecialTokenHandling; } /** * Resolve the OpenAI encoding that will be used for a given model/encoding selector. */ declare function getOpenAIEncoding(selector?: Pick): OpenAIEncoding; /** * Encode text into OpenAI token IDs using tiktoken-compatible BPE encoding. * * This is exact tokenization for OpenAI models (unlike heuristic estimators). */ declare function encode(text: string, options?: EncodeOptions): number[]; /** * Decode OpenAI token IDs into text using tiktoken-compatible BPE encoding. */ declare function decode(tokens: Iterable, options?: Pick): string; /** * Options for isWithinTokenLimit. */ interface IsWithinTokenLimitOptions { /** * Explicit OpenAI encoding override. * When provided, this takes precedence over `model`. */ encoding?: OpenAIEncoding; /** * OpenAI model ID used to select the appropriate encoding. * Note: Non-OpenAI models (claude-*, gemini-*) are rejected. */ model?: string; /** * How special tokens are handled. * - `none_raise` (default): throw if special tokens appear * - `none`: treat special tokens as regular text * - `all`: allow special tokens and encode them as special token IDs */ allowSpecial?: SpecialTokenHandling; } /** * Check if text is within a token limit, with early exit optimization. * * Returns `false` if the token count exceeds the limit, otherwise returns the * actual token count. This is significantly faster than full tokenization when * the limit is exceeded early in the text. * * @param text - The text to check * @param tokenLimit - Maximum allowed tokens (must be non-negative finite integer) * @param options - Encoding options * @returns `false` if exceeded, or the actual token count if within limit * @throws Error if tokenLimit is invalid (NaN, Infinity, negative, non-integer) * @throws Error if model is a known non-OpenAI model (claude-*, gemini-*) * * @example * ```typescript * // Returns token count if within limit * const count = isWithinTokenLimit('Hello, world!', 100, { model: 'gpt-4o' }); * if (count !== false) { * console.log(`Text has ${count} tokens`); * } * * // Returns false if exceeds limit * const result = isWithinTokenLimit(longText, 10, { model: 'gpt-4o' }); * if (result === false) { * console.log('Text exceeds 10 tokens'); * } * ``` */ declare function isWithinTokenLimit(text: string, tokenLimit: number, options?: IsWithinTokenLimitOptions): false | number; /** * Encode text yielding token chunks. Memory-efficient for large inputs. * * Yields token arrays per regex-matched piece (word/punctuation), not per token. * Returns total token count when iteration completes. * * @param text - The text to encode * @param options - Encoding options * @returns Generator that yields token arrays per piece, returns total count * * @example * ```typescript * // Stream-encode large text * let tokenCount = 0; * for (const tokenChunk of encodeGenerator(hugeText, { model: 'gpt-4o' })) { * tokenCount += tokenChunk.length; * } * * // Or get total count from return value * const gen = encodeGenerator(text, { model: 'gpt-4o' }); * let result = gen.next(); * while (!result.done) result = gen.next(); * console.log('Total tokens:', result.value); * ``` */ declare function encodeGenerator(text: string, options?: EncodeOptions): Generator; /** * Decode tokens yielding text chunks. * Uses TextDecoder streaming mode - may yield empty strings when buffering * incomplete UTF-8 sequences. * * @param tokens - Token IDs to decode * @param options - Decoding options * @returns Generator that yields text chunks * * @example * ```typescript * const tokens = encode('Hello, world!', { model: 'gpt-4o' }); * for (const textChunk of decodeGenerator(tokens, { model: 'gpt-4o' })) { * process.stdout.write(textChunk); * } * ``` */ declare function decodeGenerator(tokens: Iterable, options?: Pick): Generator; /** * Decode async token stream yielding text chunks. * Accepts single tokens or token arrays for flexibility with streaming APIs. * * Uses TextDecoder streaming mode - may yield empty strings when buffering * incomplete UTF-8 sequences. * * @param tokens - Async iterable of token IDs (numbers or number arrays) * @param options - Decoding options * @returns AsyncGenerator that yields text chunks * * @example * ```typescript * // Decode streaming LLM response * async function decodeLLMStream(tokenStream: AsyncIterable) { * for await (const text of decodeAsyncGenerator(tokenStream, { model: 'gpt-4o' })) { * process.stdout.write(text); * } * } * ``` */ declare function decodeAsyncGenerator(tokens: AsyncIterable, options?: Pick): AsyncGenerator; /** * Configuration for a specific LLM model. */ interface ModelConfig { /** Characters per token ratio for this model */ charsPerToken: number; /** Cost in USD per 1 million input tokens */ inputCostPerMillion: number; /** Cost in USD per 1 million output tokens (optional - extracted when available) */ outputCostPerMillion?: number; /** Cost in USD per 1 million cached input tokens (optional - primarily OpenAI) */ cachedInputCostPerMillion?: number; /** Cost in USD per 1 million batch input tokens (optional - primarily OpenAI) */ batchInputCostPerMillion?: number; /** Cost in USD per 1 million batch output tokens (optional - primarily OpenAI) */ batchOutputCostPerMillion?: number; } type TokenizerMode = 'heuristic' | 'openai_exact' | 'auto'; /** * Tokenizer modes supported by `estimateAsync(...)`. * * This is intentionally separate from `TokenizerMode` to avoid breaking * TypeScript users who exhaustively switch on the legacy `TokenizerMode` union. */ type TokenizerModeAsync = TokenizerMode | 'anthropic_count_tokens' | 'gemini_count_tokens' | 'gemma_sentencepiece'; /** * Input parameters for the estimate function. */ interface EstimateInput { /** The text to estimate tokens for */ text: string; /** The model ID (must exist in default config) */ model: string; /** Rounding strategy for token count (default: 'ceil') */ rounding?: 'ceil' | 'round' | 'floor'; /** * Token counting strategy. * - `heuristic` (default): use chars-per-token ratios * - `openai_exact`: use OpenAI BPE tokenization (throws if non-OpenAI model) * - `auto`: use OpenAI BPE for OpenAI models, otherwise heuristic */ tokenizer?: TokenizerMode; /** Output tokens for cost estimation (optional) */ outputTokens?: number; /** Cached input tokens for cost estimation (optional, must be <= estimatedTokens) */ cachedInputTokens?: number; /** Pricing mode: 'standard' or 'batch' (optional) */ mode?: 'standard' | 'batch'; } interface EstimateAsyncInput extends Omit { /** * Token counting strategy for async estimation. * Includes provider-backed modes that require network access or local model files. */ tokenizer?: TokenizerModeAsync; /** * Optional fetch implementation (useful for tests, edge runtimes, or custom fetch). * Defaults to globalThis.fetch. */ fetch?: typeof fetch; /** * If true, provider-backed tokenizer modes will fall back to heuristic token estimation * when the provider API is throttled/unavailable or the API key is invalid. * * This never stores API keys; it only affects error handling. * * Default: false (throw on provider errors) */ fallbackToHeuristicOnError?: boolean; /** * Configuration for Anthropic token counting. * Only used when tokenizer === 'anthropic_count_tokens'. */ anthropic?: { apiKey?: string; baseUrl?: string; version?: string; system?: string; }; /** * Configuration for Gemini token counting (Google AI Studio / Generative Language API). * Only used when tokenizer === 'gemini_count_tokens'. */ gemini?: { apiKey?: string; baseUrl?: string; }; /** * Configuration for local Gemma SentencePiece tokenization. * Only used when tokenizer === 'gemma_sentencepiece'. */ gemma?: { /** Filesystem path to a SentencePiece model file (e.g. Gemma tokenizer.model). */ modelPath?: string; }; } /** * Output from the estimate function. */ interface EstimateOutput { /** The model used for estimation */ model: string; /** Number of Unicode code points in the input */ characterCount: number; /** Estimated token count (integer, rounded per rounding strategy) */ estimatedTokens: number; /** Estimated input cost in USD */ estimatedInputCost: number; /** The chars-per-token ratio used */ charsPerToken: number; /** Which tokenizer strategy was used */ tokenizerMode?: TokenizerModeAsync; /** OpenAI encoding used when tokenizerMode is `openai_exact` */ encodingUsed?: string; /** Output tokens (echoed from input if provided) */ outputTokens?: number; /** Estimated output cost in USD (only if outputTokens provided and outputCostPerMillion available) */ estimatedOutputCost?: number; /** Estimated cached input cost in USD (only if cachedInputTokens provided and cachedInputCostPerMillion available) */ estimatedCachedInputCost?: number; /** Total estimated cost in USD (always present - sum of input + output + cached costs) */ estimatedTotalCost: number; } /** * A chat message in OpenAI legacy format (functions API). * * Note: This type intentionally excludes tool_calls, tool_call_id, and * array content. Those features require the tools API which has different * token counting logic and is not yet supported. */ interface ChatMessage { /** The role of the message author */ role: 'system' | 'user' | 'assistant' | 'function'; /** * The content of the message (text only; array content not supported). * Optional because assistant messages with function_call may omit content. */ content?: string | null; /** An optional name for the participant (for multi-user chats or function results) */ name?: string; /** Function call made by the assistant (legacy API) */ function_call?: { name: string; arguments: string; }; } /** * JSON Schema subset for function parameters. */ interface FunctionParameterProperty { type: string; description?: string; enum?: string[]; items?: FunctionParameterProperty; properties?: Record; required?: string[]; } /** * Function parameters schema. */ interface FunctionParameters { type: 'object'; properties?: Record; required?: string[]; } /** * A function definition for legacy function calling. */ interface FunctionDefinition { name: string; description?: string; parameters?: FunctionParameters; } /** * Function call control options (legacy API). */ type FunctionCallOption = 'auto' | 'none' | { name: string; }; /** * Input for counting chat completion tokens. * * Supports the legacy functions API only. For tools API support, * see the roadmap in the package documentation. */ interface ChatCompletionTokenCountInput { /** The list of messages in the conversation */ messages: ChatMessage[]; /** * The model to use for token counting. * Must be a chat-capable OpenAI model. * If using a new chat model not yet recognized, provide `encoding` instead. */ model: string; /** * Explicit encoding override. When provided, allows unrecognized models * but still rejects known non-OpenAI models (claude-*, gemini-*) and * known non-chat OpenAI models (e.g., davinci-002). */ encoding?: OpenAIEncoding; /** Function definitions (legacy API) */ functions?: FunctionDefinition[]; /** Function call control (legacy API) */ function_call?: FunctionCallOption; /** Include per-message token breakdown in output */ includeBreakdown?: boolean; } /** * Output from counting chat completion tokens. */ interface ChatCompletionTokenCountOutput { /** Total token count for the request */ totalTokens: number; /** * Tokens from messages (sum of per-message tokens). * Does NOT include completionOverheadTokens. */ messageTokens: number; /** * Tokens added for completion request overhead (reply priming). * This is the COMPLETION_REQUEST_TOKEN_OVERHEAD constant (3 tokens). * Kept separate from messageTokens for clarity. */ completionOverheadTokens: number; /** Tokens from function definitions */ functionTokens: number; /** Tokens from function_call setting */ functionCallTokens: number; /** Whether exact tokenization was used (always true for supported inputs) */ exact: true; /** The encoding used */ encoding: OpenAIEncoding; /** * Breakdown by message (only if includeBreakdown: true). * * Note on field semantics: * - `stringTokens`: tokens from encoding role, content, name, function_call fields * - `overheadTokens`: fixed overhead (MESSAGE_TOKEN_OVERHEAD, NAME_TOKEN_OVERHEAD, etc.) * including the function-role discount when applicable * * The completionOverheadTokens (reply priming) is NOT included in this breakdown * as it applies to the request as a whole, not individual messages. */ messageBreakdown?: Array<{ role: string; stringTokens: number; overheadTokens: number; totalTokens: number; }>; } /** * Estimate token count and cost for the given text and model. * * @param input - The estimation input parameters * @returns The estimation output with token count and cost * @throws Error if the model is not found in the configuration * * @example * ```typescript * const result = estimate({ * text: 'Hello, world!', * model: 'gpt-4o' * }); * console.log(result.estimatedTokens); // 4 * console.log(result.estimatedInputCost); // 0.00001 * ``` */ declare function estimate(input: EstimateInput): EstimateOutput; declare function estimateAsync(input: EstimateAsyncInput): Promise; /** * Input parameters for estimateCost(). */ interface EstimateCostInput { /** The model ID */ model: string; /** Total input tokens (includes cached) */ inputTokens: number; /** Output tokens (if > 0, requires outputCostPerMillion) */ outputTokens?: number; /** Cached input tokens (must be <= inputTokens) */ cachedInputTokens?: number; /** Pricing mode: 'standard' or 'batch' */ mode?: 'standard' | 'batch'; } /** * Structured cost estimate result. */ interface CostEstimate { /** The model used */ model: string; /** The pricing mode used */ mode: 'standard' | 'batch'; /** Token counts echoed back */ tokens: { /** Total input tokens (includes cached) */ input: number; /** Cached input tokens (subset of input priced at cached rate) */ cachedInput: number; /** Non-cached input tokens (input - cachedInput) */ nonCachedInput: number; /** Output tokens */ output: number; }; /** Cost breakdown in USD (no rounding applied) */ costs: { /** Non-cached input cost */ input: number; /** Cached input cost */ cachedInput: number; /** Output cost */ output: number; /** Sum of all costs */ total: number; }; /** Per-million rates used (for transparency) */ rates: { inputPerMillion: number; outputPerMillion?: number; cachedInputPerMillion?: number; batchInputPerMillion?: number; batchOutputPerMillion?: number; }; } /** * Options for estimateCostFromText (sync). */ interface EstimateCostFromTextOptions { /** The model ID */ model: string; /** Input text to count tokens for */ inputText: string; /** Output text to count tokens for (auto-counts output tokens) */ outputText?: string; /** Manual output token count (takes precedence over outputText) */ outputTokens?: number; /** Cached input tokens */ cachedInputTokens?: number; /** Pricing mode */ mode?: 'standard' | 'batch'; } /** * Options for estimateCostFromTextAsync. * Forwards all EstimateAsyncInput options (minus 'text') for provider-backed counting. */ type EstimateCostFromTextAsyncOptions = { /** The model ID */ model: string; /** Input text to count tokens for */ inputText: string; /** Output text to count tokens for (auto-counts output tokens) */ outputText?: string; /** Manual output token count (takes precedence over outputText) */ outputTokens?: number; /** Cached input tokens */ cachedInputTokens?: number; /** Pricing mode */ mode?: 'standard' | 'batch'; } & Omit; /** * Estimate cost from explicit token counts. * * @throws {Error} if model is unknown * @throws {Error} if outputTokens > 0 but outputCostPerMillion is missing * @throws {Error} if cachedInputTokens > inputTokens * @throws {Error} if cachedInputTokens > 0 but cachedInputCostPerMillion is missing * @throws {Error} if mode='batch' but batch rates are missing * @throws {Error} if mode='batch' and cachedInputTokens > 0 * @throws {Error} if any token count is negative or non-finite */ declare function estimateCost(options: EstimateCostInput): CostEstimate; /** * Sync helper: estimate cost from text (uses countTokens internally). * Uses OpenAI exact tokenization when available, else heuristic. * * Precedence rules: * - outputTokens takes precedence over outputText * - If both omitted, outputTokens defaults to 0 * - If outputText provided, tokens are counted using countTokens (same as input) */ declare function estimateCostFromText(options: EstimateCostFromTextOptions): CostEstimate; /** * Async helper: estimate cost from text using provider-backed tokenization. * Uses provider APIs (Anthropic, Gemini) when available for exact counts. * * Precedence rules: * - outputTokens takes precedence over outputText * - If both omitted, outputTokens defaults to 0 * - If outputText provided, tokens are counted using the same tokenizer mode as input */ declare function estimateCostFromTextAsync(options: EstimateCostFromTextAsyncOptions): Promise; /** * Quick total cost helper. * * @throws {Error} if output pricing is missing when outputTokens > 0 */ declare function getTotalCost(model: string, inputTokens: number, outputTokens?: number): number; /** * Default model configurations. * * AUTO-GENERATED FILE - DO NOT EDIT MANUALLY * Last updated: 2026-01-19 * * Sources: * - OpenAI: https://platform.openai.com/docs/pricing * - Anthropic: https://www.anthropic.com/pricing * - Google: https://ai.google.dev/gemini-api/docs/pricing * * This file is automatically updated weekly by GitHub Actions. */ declare const LAST_UPDATED = "2026-01-19"; declare const DEFAULT_MODELS: Readonly>>; /** * Get configuration for a specific model. * @param model - The model ID to look up * @returns The model configuration * @throws Error if model is not found */ declare function getModelConfig(model: string): ModelConfig; /** * Get list of all available model IDs. * @returns Array of model ID strings */ declare function getAvailableModels(): string[]; interface TokenCountInput { text: string; model: string; } interface TokenCountOutput { tokens: number; exact: boolean; encoding?: OpenAIEncoding; } /** * Count tokens for a given model. * * - OpenAI models: exact BPE tokenization * - Other providers: heuristic estimate (chars-per-token) */ declare function countTokens(input: TokenCountInput): TokenCountOutput; /** * Chat completion token counting for OpenAI's legacy functions API. * * Achieves exact token count parity for normal text inputs. * Note: special token handling treats special-token-like strings * as regular text (does not throw). */ /** * Count tokens for an OpenAI chat completion request with legacy functions API. * * Achieves exact token count parity with OpenAI's actual API usage. * * @throws {Error} If model is not an OpenAI model (unless encoding override provided) * @throws {Error} If tools, tool_choice, tool_calls, or tool_call_id are present * @throws {Error} If any message has non-string content (arrays, numbers, objects) * * @example * ```typescript * const result = countChatCompletionTokens({ * messages: [ * { role: 'system', content: 'You are a helpful assistant.' }, * { role: 'user', content: 'Hello!' } * ], * model: 'gpt-4o', * functions: [{ * name: 'get_weather', * description: 'Get weather for a location', * parameters: { * type: 'object', * properties: { * location: { type: 'string', description: 'City name' } * } * } * }] * }); * * console.log(result.totalTokens); * ``` */ declare function countChatCompletionTokens(input: ChatCompletionTokenCountInput): ChatCompletionTokenCountOutput; /** * Input for isChatWithinTokenLimit. * Object-style input to match countChatCompletionTokens API. */ interface IsChatWithinTokenLimitInput { messages: ChatMessage[]; model: string; tokenLimit: number; encoding?: OpenAIEncoding; functions?: FunctionDefinition[]; function_call?: FunctionCallOption; } /** * Check if chat messages are within a token limit, with early exit optimization. * * Uses object-style input to match countChatCompletionTokens API. * Returns `false` if the token count exceeds the limit, otherwise returns * the actual token count. * * This is significantly faster than full tokenization when the limit is * exceeded early in the input. * * @throws {Error} If tokenLimit is invalid (NaN, Infinity, negative, non-integer) * @throws {Error} If model is not an OpenAI model (unless encoding override provided) * @throws {Error} If tools, tool_choice, tool_calls, or tool_call_id are present * @throws {Error} If any message has non-string content (arrays, numbers, objects) * * @example * ```typescript * const result = isChatWithinTokenLimit({ * messages: [ * { role: 'system', content: 'You are a helpful assistant.' }, * { role: 'user', content: 'Hello!' } * ], * model: 'gpt-4o', * tokenLimit: 100, * }); * * if (result === false) { * console.log('Messages exceed token limit'); * } else { * console.log(`Messages use ${result} tokens`); * } * ``` */ declare function isChatWithinTokenLimit(input: IsChatWithinTokenLimitInput): false | number; /** * Chat-aware tokenization using ChatML format. * * Encodes chat messages into ChatML message prompt tokens including special * delimiter tokens (<|im_start|>, <|im_sep|>, <|im_end|>). */ /** * Options for encodeChat. */ interface EncodeChatOptions { /** * OpenAI model ID used to select the appropriate encoding. * Note: Non-OpenAI models (claude-*, gemini-*) are rejected. */ model?: string; /** * Explicit OpenAI encoding override. * When provided, this takes precedence over `model`. */ encoding?: OpenAIEncoding; /** * Prime the output with the start of an assistant response. * When true (default), appends <|im_start|>assistant<|im_sep|> at the end. * Set to false to get just the messages without assistant priming. */ primeAssistant?: boolean; } /** * Encode chat messages into token IDs using ChatML format. * * Returns the exact token sequence that OpenAI models expect for chat * completions, including special delimiter tokens. * * @param messages - Array of chat messages * @param options - Encoding options * @returns Token IDs representing the chat prompt * * @example * ```typescript * const tokens = encodeChat([ * { role: 'system', content: 'You are helpful.' }, * { role: 'user', content: 'Hello!' } * ], { model: 'gpt-4o' }); * ``` */ declare function encodeChat(messages: ChatMessage[], options?: EncodeChatOptions): number[]; /** * Generator version of encodeChat. Yields token arrays per message component. * Returns total token count. * * Yields tokens in the following order per message: * - [imStart] (1 token) * - role tokens * - [imSep] (1 token) * - content tokens (if present, yielded in chunks) * - function_call tokens (if present) * - [imEnd] (1 token) * * If primeAssistant is true (default), also yields assistant priming tokens at the end. * * @param messages - Array or iterable of chat messages * @param options - Encoding options * @returns Generator that yields token arrays per component, returns total count * * @example * ```typescript * const messages = [ * { role: 'system', content: 'You are helpful.' }, * { role: 'user', content: 'Hello!' } * ]; * * // Stream-encode messages * for (const tokenChunk of encodeChatGenerator(messages, { model: 'gpt-4o' })) { * console.log('Chunk:', tokenChunk); * } * * // Get total count from return value * const gen = encodeChatGenerator(messages, { model: 'gpt-4o' }); * let result = gen.next(); * while (!result.done) result = gen.next(); * console.log('Total tokens:', result.value); * ``` */ declare function encodeChatGenerator(messages: ChatMessage[] | Iterable, options?: EncodeChatOptions): Generator; interface AnthropicCountTokensParams { /** Claude model id, e.g. `claude-sonnet-4-5` */ model: string; /** Anthropic API key. If omitted, uses process.env.ANTHROPIC_API_KEY */ apiKey?: string; /** Text-only helper; converted into a single user message. */ text?: string; /** Optional system prompt. */ system?: string; /** Full messages payload (wins over `text` when provided). */ messages?: unknown; /** Override API base URL (default: https://api.anthropic.com) */ baseUrl?: string; /** Override Anthropic version header (default: 2023-06-01) */ version?: string; /** Optional fetch implementation. Defaults to globalThis.fetch. */ fetch?: typeof fetch; } declare function countAnthropicInputTokens(params: AnthropicCountTokensParams): Promise; interface GeminiCountTokensParams { /** Gemini model id, e.g. `gemini-2.0-flash` */ model: string; /** Gemini API key. If omitted, uses process.env.GEMINI_API_KEY */ apiKey?: string; /** Text-only helper; converted into a basic `contents` payload. */ text?: string; /** Full `contents` payload (wins over `text` when provided). */ contents?: unknown; /** Override API base URL (default: https://generativelanguage.googleapis.com) */ baseUrl?: string; /** Optional fetch implementation. Defaults to globalThis.fetch. */ fetch?: typeof fetch; } declare function countGeminiTokens(params: GeminiCountTokensParams): Promise; /** * Gemma SentencePiece Token Counter * * Uses our pure TypeScript SentencePiece implementation. */ interface GemmaSentencePieceCountTokensParams { /** Filesystem path to a SentencePiece model file (e.g. Gemma `tokenizer.model`). */ modelPath: string; text: string; } /** * Count tokens using a SentencePiece model file. * * @param params The model path and text to tokenize * @returns The number of tokens */ declare function countGemmaSentencePieceTokens(params: GemmaSentencePieceCountTokensParams): Promise; /** * SentencePiece Tokenizer * * Main tokenizer class that orchestrates parsing, normalization, and encoding/decoding. * Supports both SentencePiece .model files (protobuf) and HuggingFace tokenizer.json files. */ /** * Tokenizer interface */ interface SentencePieceTokenizer { encode(text: string): number[]; decode(tokens: number[]): string; readonly vocabSize: number; readonly algorithm: 'bpe' | 'unigram'; } /** * Options for creating a tokenizer from in-memory data */ interface DataOptions { /** Model data as Uint8Array or ArrayBuffer */ modelData: Uint8Array | ArrayBuffer; /** Format hint ('protobuf' or 'json', auto-detected if omitted) */ format?: 'protobuf' | 'json'; } /** * Create a tokenizer from in-memory model data * * This is the sync API suitable for browser/serverless environments. */ declare function getSentencePieceTokenizer(options: DataOptions): SentencePieceTokenizer; /** * Encode text to token IDs */ declare function encodeSentencePiece(text: string, options: DataOptions): number[]; /** * Decode token IDs to text */ declare function decodeSentencePiece(tokens: number[], options: DataOptions): string; /** * Count tokens in text */ declare function countSentencePieceTokens(text: string, options: DataOptions): number; /** * Async SentencePiece Tokenizer (Node.js) * * Provides async file-based API for loading tokenizers from disk. * This module uses Node.js fs APIs and is not browser-compatible. */ /** * Options for loading a tokenizer from a file */ interface FileOptions { /** Path to .model or tokenizer.json file */ modelPath: string; /** Format hint ('protobuf' or 'json', auto-detected from extension if omitted) */ format?: 'protobuf' | 'json'; } /** * Load a tokenizer from a file path * * This is the async API suitable for Node.js applications. * * @param options File loading options * @returns Promise resolving to a tokenizer instance */ declare function loadSentencePieceTokenizer(options: FileOptions): Promise; /** * Encode text to token IDs (async, file-based) */ declare function encodeSentencePieceAsync(text: string, options: FileOptions): Promise; /** * Decode token IDs to text (async, file-based) */ declare function decodeSentencePieceAsync(tokens: number[], options: FileOptions): Promise; /** * Count tokens in text (async, file-based) */ declare function countSentencePieceTokensAsync(text: string, options: FileOptions): Promise; /** * Model Registry * * Official model sources with pre-computed SHA-256 hashes. * Hashes are verified on download to ensure integrity. * * To verify hashes: npm run verify:hashes */ interface ModelInfo { url: string; sha256: string; filename: string; algorithm: 'bpe' | 'unigram'; vocabSize: number; gated: boolean; } /** * Registry of known tokenizer models * * SHA-256 hashes are computed from the canonical source files. * Run `npm run verify:hashes` to verify all hashes are correct. */ declare const MODEL_REGISTRY: Record; type KnownTokenizer = keyof typeof MODEL_REGISTRY; /** * Model Download Helper * * Downloads SentencePiece models from official sources with verification. * Supports caching, SHA-256 verification, and HuggingFace authentication. * * NOTE: This module uses Node.js APIs (fs, path, crypto, os) and is not browser-compatible. */ interface DownloadOptions { /** Name of the tokenizer to download */ tokenizer: KnownTokenizer; /** Directory to cache models (default: SENTENCEPIECE_MODEL_CACHE_DIR or ~/.cache/sentencepiece) */ cacheDir?: string; /** Enable network download (default: false - fails if not cached) */ allowDownload?: boolean; /** Verify SHA-256 hash after download (default: true) */ verifyHash?: boolean; /** HuggingFace auth token for gated models (or use HF_TOKEN env var) */ authToken?: string; /** Custom URL to download from (hash still verified) */ customUrl?: string; } /** * Ensure a SentencePiece model is available locally. * Downloads from official source if not cached. * * @returns Absolute path to the cached .model file */ declare function ensureSentencePieceModel(options: DownloadOptions): Promise; /** * SentencePiece protobuf schema types * Based on sentencepiece_model.proto */ interface ModelProto { pieces: SentencePiece[]; trainerSpec?: TrainerSpec; normalizerSpec?: NormalizerSpec; selfTestData?: SelfTestData; denormalizerSpec?: NormalizerSpec; } interface SentencePiece { piece: string; score: number; type: SentencePieceType; } declare enum SentencePieceType { NORMAL = 1, UNKNOWN = 2, CONTROL = 3, USER_DEFINED = 4, UNUSED = 5, BYTE = 6 } interface TrainerSpec { modelType: ModelType; vocabSize: number; byteFallback: boolean; splitDigits: boolean; splitByWhitespace: boolean; splitByUnicodeScript: boolean; treatWhitespaceAsSuffix: boolean; unkId: number; bosId: number; eosId: number; padId: number; unkPiece: string; bosPiece: string; eosPiece: string; padPiece: string; maxSentencepieceLength: number; } declare enum ModelType { UNIGRAM = 1, BPE = 2, WORD = 3, CHAR = 4 } interface NormalizerSpec { name: string; precompiledCharsmap: Uint8Array; addDummyPrefix: boolean; removeExtraWhitespaces: boolean; escapeWhitespaces: boolean; normalizationRuleTsv: string; } interface SelfTestData { samples: Array<{ input: string; expected: string; }>; } /** * Parsed Model Cache * * In-memory cache for parsed models to avoid re-parsing on every call. */ /** * Clear the model cache */ declare function clearModelCache(): void; /** * SentencePiece ModelProto decoder * Parses .model files (protobuf format) */ /** * Parse a SentencePiece .model file */ declare function parseModelProto(buffer: Uint8Array): ModelProto; export { type AnthropicCountTokensParams, type ChatCompletionTokenCountInput, type ChatCompletionTokenCountOutput, type ChatMessage, type CostEstimate, DEFAULT_MODELS, type DataOptions, type DownloadOptions, type EncodeChatOptions, type EncodeOptions, type EstimateAsyncInput, type EstimateCostFromTextAsyncOptions, type EstimateCostFromTextOptions, type EstimateCostInput, type EstimateInput, type EstimateOutput, type FileOptions, type FunctionCallOption, type FunctionDefinition, type FunctionParameterProperty, type FunctionParameters, type GeminiCountTokensParams, type GemmaSentencePieceCountTokensParams, type IsChatWithinTokenLimitInput, type IsWithinTokenLimitOptions, type KnownTokenizer, LAST_UPDATED, type ModelConfig, type ModelInfo, type ModelProto, type NormalizerSpec, type OpenAIEncoding, type SentencePiece, type SentencePieceTokenizer, type SpecialTokenHandling, type TokenCountInput, type TokenCountOutput, type TokenizerMode, type TokenizerModeAsync, type TrainerSpec, clearModelCache, countAnthropicInputTokens, countChatCompletionTokens, countGeminiTokens, countGemmaSentencePieceTokens, countSentencePieceTokens, countSentencePieceTokensAsync, countTokens, decode, decodeAsyncGenerator, decodeGenerator, decodeSentencePiece, decodeSentencePieceAsync, encode, encodeChat, encodeChatGenerator, encodeGenerator, encodeSentencePiece, encodeSentencePieceAsync, ensureSentencePieceModel, estimate, estimateAsync, estimateCost, estimateCostFromText, estimateCostFromTextAsync, getAvailableModels, getModelConfig, getOpenAIEncoding, getSentencePieceTokenizer, getTotalCost, isChatWithinTokenLimit, isWithinTokenLimit, loadSentencePieceTokenizer, parseModelProto };