Roo-Code/src/utils/tiktoken.ts
Chris Estreich 65cb9244ee
Count tokens worker (#3037)
* Count tokens worker

* Appease knip
2025-04-29 12:29:25 -07:00

46 lines
1.3 KiB
TypeScript

import { Anthropic } from "@anthropic-ai/sdk"
import { Tiktoken } from "tiktoken/lite"
import o200kBase from "tiktoken/encoders/o200k_base"
const TOKEN_FUDGE_FACTOR = 1.5
let encoder: Tiktoken | null = null
export async function tiktoken(content: Anthropic.Messages.ContentBlockParam[]): Promise<number> {
if (content.length === 0) {
return 0
}
let totalTokens = 0
// Lazily create and cache the encoder if it doesn't exist.
if (!encoder) {
encoder = new Tiktoken(o200kBase.bpe_ranks, o200kBase.special_tokens, o200kBase.pat_str)
}
// Process each content block using the cached encoder.
for (const block of content) {
if (block.type === "text") {
const text = block.text || ""
if (text.length > 0) {
const tokens = encoder.encode(text)
totalTokens += tokens.length
}
} else if (block.type === "image") {
// For images, calculate based on data size.
const imageSource = block.source
if (imageSource && typeof imageSource === "object" && "data" in imageSource) {
const base64Data = imageSource.data as string
totalTokens += Math.ceil(Math.sqrt(base64Data.length))
} else {
totalTokens += 300 // Conservative estimate for unknown images
}
}
}
// Add a fudge factor to account for the fact that tiktoken is not always
// accurate.
return Math.ceil(totalTokens * TOKEN_FUDGE_FACTOR)
}