"use strict";const k=require("crypto");class h extends Error{constructor(e,s,t){super(e),this.strategy=s,this.context=t,this.name="CompactionError"}}class u extends h{constructor(e,s,t){super(`Token estimation failed for model ${t}: ${e}`,s),this.name="TokenEstimationError"}}class g extends h{constructor(e){super(`Compaction strategy '${e}' not found`,e),this.name="StrategyNotFoundError"}}const o={};class f{cache=new Map;maxSize;ttl;constructor(e=1e3,s=300*1e3){this.maxSize=e,this.ttl=s}getCacheKey(e,s){const t=k.createHash("md5").update(e).digest("hex");return`${s}:${t}`}get(e,s){const t=this.getCacheKey(e,s),i=this.cache.get(t);if(i){if(Date.now()-i.timestamp>this.ttl){this.cache.delete(t);return}return i.tokenCount}}set(e,s,t){const i=this.getCacheKey(e,s);if(this.cache.size>=this.maxSize){const r=this.cache.keys().next();r.done||this.cache.delete(r.value)}this.cache.set(i,{contentHash:k.createHash("md5").update(e).digest("hex"),modelName:s,tokenCount:t,timestamp:Date.now()})}cleanup(){const e=Date.now();for(const[s,t]of this.cache.entries())e-t.timestamp>this.ttl&&this.cache.delete(s)}getStats(){return{size:this.cache.size,hitRate:0}}}class T{cache;config;tokenizerTypeCache=new Map;constructor(e={}){this.config={defaultTokenizer:"generic",cacheSize:1e3,cacheTtl:300*1e3,enableBatching:!0,batchSize:10,...e},this.cache=new f(this.config.cacheSize,this.config.cacheTtl)}getTokenizerType(e){if(this.tokenizerTypeCache.has(e)){const t=this.tokenizerTypeCache.get(e);if(t)return t}let s=this.config.defaultTokenizer;if(o[e])s=o[e];else for(const[t,i]of Object.entries(o))if(e.toLowerCase().includes(t.toLowerCase())){s=i;break}return this.tokenizerTypeCache.set(e,s),s}estimateTokens(e,s){if(!e||e.length===0)return 0;const t=this.cache.get(e,s);if(t!==void 0)return t;const i=this.getTokenizerType(s);let n;try{switch(i){case"tiktoken":n=this.estimateWithTiktoken(e,s);break;case"llama":n=this.estimateWithLlama(e);break;case"claude":n=this.estimateWithClaude(e);break;default:n=this.estimateGeneric(e);break}}catch{n=this.estimateGeneric(e)}return this.cache.set(e,s,n),n}estimateWithTiktoken(e,s){try{return!e||e.length===0?0:this.estimateGeneric(e)}catch{throw new u(`Failed to load tiktoken for model ${s}`,"tiktoken",s)}}estimateWithLlama(e){return!e||e.length===0?0:Math.ceil(e.length/3.5)}estimateWithClaude(e){return!e||e.length===0?0:Math.ceil(e.length/4)}estimateGeneric(e){if(!e||e.length===0)return 0;const s=Math.ceil(e.length/4),t=e.length>0?Math.ceil(e.split(`
`).length*.5):0,i=(e.match(/```/g)||[]).length*2;return s+t+i}estimateMessageTokens(e,s){let t=0;t+=10;for(const i of e.entries)switch(i.type){case"text":t+=this.estimateTokens(i.text,s);break;case"document":i.document.type==="file"&&(t+=100);break;case"toolUse":{const n=JSON.stringify(i.args);t+=this.estimateTokens(n,s),t+=20;break}case"toolUseResponse":i.message&&(t+=this.estimateTokens(i.message,s));break;default:t+=50}return t}estimateContextTokens(e,s){let t=0;if(t+=50,this.config.enableBatching&&e.messages.length>this.config.batchSize){const i=this.chunkArray(e.messages,this.config.batchSize);for(const n of i){const r=n.map(c=>this.estimateMessageTokens(c,s));t+=r.reduce((c,l)=>c+l,0)}}else{const i=e.messages.map(n=>this.estimateMessageTokens(n,s));t+=i.reduce((n,r)=>n+r,0)}return t}chunkArray(e,s){const t=[];for(let i=0;i<e.length;i+=s)t.push(e.slice(i,i+s));return t}cleanup(){this.cache.cleanup(),this.tokenizerTypeCache.clear()}getStats(){return{cacheStats:this.cache.getStats()}}}exports.CompactionError=h;exports.StrategyNotFoundError=g;exports.TokenEstimationError=u;exports.TokenEstimator=T;
//# sourceMappingURL=token-estimator-7OLZJiZ7.cjs.map
