Repository navigation
fix: reuse one tokenizer instead of building one per countTokens call - #639
Open
kernel-oops wants to merge 1 commit into
Open
kernel-oops wants to merge 1 commit into
kernel-oops wants to merge 1 commit into
Conversation
@anthropic-ai/tokenizer's countTokens() constructs and frees a new WASM Tiktoken on every call (~70 ms). syncToolCache counts every uncached tool part on each transform, and entries evicted by MAX_TOOL_CACHE_SIZE are re-counted, so long sessions blocked the host's event loop for seconds per request. Build the tokenizer once and reuse it; counts are identical. Fixes Tarquinen#638 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RG8UhiogA1Ho2eZRx8tn2y
|
+1 here this is a critical issue |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #638
@anthropic-ai/tokenizer'scountTokens()builds and frees a new WASMTiktokenon every call. That takes about 70 ms, against about 0.19 ms forencode()on a tokenizer that's reused.syncToolCachecounts every uncached tool part on each chat-messages transform, and it re-counts entries onceMAX_TOOL_CACHE_SIZEevicts them. On long sessions this blocked the host's event loop for seconds per request, which also stalled every other session on the same OpenCode server.Change
lib/token-utils.tsnow gets the package'sgetTokenizer, builds the tokenizer lazily on first use and reuses it. It keeps the sameNFKCnormalisation and"all"special-token handling ascountTokens(), so the counts are identical. The existingtry/catchincountTokensstill falls back to the length estimate if anything throws.Verification
tests/token-counting.test.ts: the counts match the package'scountTokens()on plain, Unicode (ligatures, emoji), JSON, long and special-token inputs, and 200 calls finish within 2 s. The timing assertion fails on the current code, where 200 calls take about 14 s.npm run format:check,npm run typecheckandnpm testall pass (120 tests, plus 8 intests/logger).countTokenswas the stack beneathsyncToolCache.🤖 Generated with Claude Code
https://claude.ai/code/session_01RG8UhiogA1Ho2eZRx8tn2y