(modelName: ModelName, text: string)
| 144 | } |
| 145 | |
| 146 | async function countTokensInternal(modelName: ModelName, text: string): Promise<number> { |
| 147 | assert(typeof text === "string", "Tokenizer countTokens expects string input"); |
| 148 | if (text.length === 0) { |
| 149 | return 0; |
| 150 | } |
| 151 | |
| 152 | const key = buildCacheKey(modelName, text); |
| 153 | const cached = tokenCountCache.get(key); |
| 154 | if (cached !== undefined) { |
| 155 | return cached; |
| 156 | } |
| 157 | |
| 158 | let pending = inFlightCounts.get(key); |
| 159 | if (!pending) { |
| 160 | const payload: CountTokensInput = { modelName, input: text }; |
| 161 | pending = run<number>("countTokens", payload) |
| 162 | .then((value: unknown) => { |
| 163 | assert( |
| 164 | typeof value === "number" && Number.isFinite(value) && value >= 0, |
| 165 | "Tokenizer must return a non-negative finite token count" |
| 166 | ); |
| 167 | tokenCountCache.set(key, value); |
| 168 | inFlightCounts.delete(key); |
| 169 | return value; |
| 170 | }) |
| 171 | .catch((error) => { |
| 172 | inFlightCounts.delete(key); |
| 173 | throw error; |
| 174 | }); |
| 175 | inFlightCounts.set(key, pending); |
| 176 | } |
| 177 | return pending; |
| 178 | } |
| 179 | |
| 180 | export function loadTokenizerModules( |
| 181 | modelsToWarm: string[] = Array.from(DEFAULT_WARM_MODELS) |
no test coverage detected