@kunal_dutt/token-lens 0.2.17 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gateway.mjs CHANGED
@@ -1,13 +1,17 @@
1
1
  import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
2
- import{readFileSync as Mr}from"node:fs";var ha={port:8080,host:"0.0.0.0",mode:"optimize",level:"auto",safe:{prompt:!0,minifyJson:!0,collapseRepeats:!0,dedupeToolOutputs:!0,dedupePassages:!0,dedupeImages:!0,promptCaching:!0,dedupeRetries:!0,cacheEmbeddings:!0},optIn:{elideOldToolOutputs:!1,lazyTools:!1,trimToolFields:!1,compactJson:!1,parkToolOutputs:!1,flex:!1,warmCache:!1},verify:{sampleRate:.05,minSimilarity:.8,maxShareOfSavings:.2,freeChecks:5,probation:5},runBudget:{},batch:{flushSeconds:60,pollSeconds:60,maxRequests:1e3,discount:.5},flexDiscount:.5,embeddingsCacheMB:256,priceTiers:[],storage:{keyPrefix:"token-lens:",flushSeconds:10,runDays:7},retryWindowSeconds:120,blockOverContext:!1,upstreams:{},routes:[],models:[],clientKeys:[],maxBodyBytes:32*1024*1024,maxRuns:2e3,logRequests:!0,reportToolArgs:!1};function Un(a,e){if(typeof a=="string"&&a.startsWith("env:")){let n=a.slice(4);return e[n]??""}return Array.isArray(a)?a.map(n=>Un(n,e)):a&&typeof a=="object"?Object.fromEntries(Object.entries(a).map(([n,i])=>[n,Un(i,e)])):a}function jr(a){let e={};return(a.OPENAI_API_KEY||a.OPENAI_BASE_URL)&&(e.openai={type:"openai",baseUrl:a.OPENAI_BASE_URL||"https://api.openai.com/v1",apiKey:a.OPENAI_API_KEY}),(a.ANTHROPIC_API_KEY||a.ANTHROPIC_BASE_URL)&&(e.anthropic={type:"anthropic",baseUrl:a.ANTHROPIC_BASE_URL||"https://api.anthropic.com",apiKey:a.ANTHROPIC_API_KEY}),e}function Or(a={},e={}){let n=Un(a,e),i={...ha,...n,safe:{...ha.safe,...n.safe},optIn:{...ha.optIn,...n.optIn},verify:{...ha.verify,...n.verify},batch:{...ha.batch,...n.batch},storage:{...ha.storage,...n.storage},upstreams:{...jr(e),...n.upstreams}};e.PORT&&(i.port=Number(e.PORT)),e.TOKEN_LENS_MODE&&(i.mode=e.TOKEN_LENS_MODE),e.TOKEN_LENS_VERIFY_RATE&&(i.verify.sampleRate=Number(e.TOKEN_LENS_VERIFY_RATE)),e.TOKEN_LENS_ADMIN_KEY&&(i.adminKey=e.TOKEN_LENS_ADMIN_KEY),e.TOKEN_LENS_REDIS_URL&&(i.storage.redisUrl=e.TOKEN_LENS_REDIS_URL),e.TOKEN_LENS_STORAGE_FILE&&(i.storage.file=e.TOKEN_LENS_STORAGE_FILE),e.TOKEN_LENS_CLIENT_KEYS&&(i.clientKeys=[...i.clientKeys,...e.TOKEN_LENS_CLIENT_KEYS.split(",").map(r=>r.trim()).filter(Boolean).map((r,t)=>{let[s,o]=r.includes(":")?r.split(/:(.*)/s):[`client-${t+1}`,r];return{name:s,key:o}})]),i.clientKeys=i.clientKeys.filter(r=>r.key);for(let[r,t]of Object.entries(i.upstreams)){if(t.type!=="openai"&&t.type!=="anthropic")throw new Error(`Upstream "${r}": type must be "openai" or "anthropic".`);if(!t.baseUrl)throw new Error(`Upstream "${r}" needs a baseUrl.`);t.baseUrl=t.baseUrl.replace(/\/+$/,""),t.apiKey||delete t.apiKey}for(let r of i.routes)if(!i.upstreams[r.upstream])throw new Error(`Route "${r.model}" points at unknown upstream "${r.upstream}".`);if(i.defaultUpstream&&!i.upstreams[i.defaultUpstream])throw new Error(`defaultUpstream "${i.defaultUpstream}" is not defined.`);return i}function Vi(a=process.env){let e=a.TOKEN_LENS_CONFIG,n=e?JSON.parse(Mr(e,"utf8")):{};return Or(n,a)}import{createServer as Eo}from"node:http";import{timingSafeEqual as Ao}from"node:crypto";var ba=a=>a.toLocaleString("en-US");function Ca(a){let{profile:e,task:n,signals:i,promptTokens:r,usage:t,text:s}=a,o=[];if(n==="coding"&&i.pastedTokens>1500&&o.push({id:"paste-less-code",text:`About ${ba(i.pastedTokens)} tokens of pasted code. Paste only the functions involved.`,saves:"input"}),n==="debugging"&&i.hasLogs&&i.pastedTokens>800&&o.push({id:"trim-logs",text:"Long log pasted. The first error and its stack are usually enough; Optimize collapses repeated lines and library frames.",saves:"input"}),n==="analysis"&&i.hasData&&i.pastedTokens>2e3&&o.push({id:"sample-data",text:"Large table pasted. The header plus ~20 sample rows and a description of the rest is usually enough; or attach the file instead.",saves:"input"}),i.pastedTokens>t.window*.4&&o.push({id:"split-material",text:`The pasted material is ${Math.round(i.pastedTokens/t.window*100)}% of ${e.label}'s context. Split it into parts or paste only what's needed.`,saves:"input"}),e.family==="anthropic"&&i.pastedTokens>300&&!/<[a-z][\w-]*>/i.test(s))for(let u of e.notes??[])o.push({id:"family-note",text:u,saves:"input"});t.zone==="hot"||t.zone==="full"?o.push({id:"handoff",text:`This chat fills about ${Math.round(t.ratio*100)}% of ${e.label}'s context. Older messages will be dropped or compacted soon. Hand off to a new chat.`,saves:"input"}):(t.longChat||t.zone==="warm")&&o.push({id:"handoff",text:`Every new message re-reads about ${ba(t.conversationTokens)} tokens of history. A handoff brief and a new chat cut that.`,saves:"input"});let l=e.pricing?.longContext,c=t.conversationTokens+r;return l&&e.pricing&&c>=l.aboveTokens*.85&&o.push({id:"price-threshold",text:c>l.aboveTokens?`This message reads \u2248${ba(c)} tokens, past ${ba(l.aboveTokens)}, so ${e.label} bills all of it at $${l.inputPerMTok}/M instead of $${e.pricing.inputPerMTok}/M. Continuing from a handoff brief in a new chat brings it back under.`:`This chat is \u2248${ba(c)} tokens; past ${ba(l.aboveTokens)}, ${e.label} bills every message at $${l.inputPerMTok}/M instead of $${e.pricing.inputPerMTok}/M. Hand off to a new chat before then.`,saves:"input"}),o}function Ra(a,e,n,i){let r=i&&i>0?i:n.contextWindow,t=(a+e)/r,s=t>=.95?"full":t>=.8?"hot":t>=.5?"warm":"ok";return{conversationTokens:a,promptTokens:e,window:r,ratio:t,zone:s,longChat:a>=4e4}}function Wi(a,e){return a!=="auto"?a:e.zone==="hot"||e.zone==="full"?"aggressive":"balanced"}var Dr={coding:"the files and functions involved, the current state of the code (only the parts still changing, verbatim), and what is left to build",debugging:"the bug, what has been ruled out, the most likely cause, and the exact error message",writing:"the audience, tone, the current outline, and any passages I approved (verbatim)",editing:"the style rules we settled on and which parts are already done",analysis:"the dataset's shape, the findings so far with their numbers, and the next questions",research:"the question, the answers found so far with their sources, and what is still open"};function Ki(a){return["Write a handoff brief of this conversation that I can paste into a new chat to continue without the history.",`Cover: ${Dr[a]??"the goal, the decisions made, and the current state"}; plus open questions and my preferences.`,"Use terse bullets, under 250 words, and nothing else."].join(" ")}var le="<|endoftext|>",Oe="<|fim_prefix|>",De="<|fim_middle|>",Ne="<|fim_suffix|>",ia="<|im_start|>",ta="<|im_end|>",Le="<|im_sep|>",Be="<|endofprompt|>",Hn="<|startoftext|>",Pa="<|start|>",za="<|end|>",Ia="<|message|>",xa="<|channel|>",Ma="<|return|>",ja="<|constrain|>",Oa="<|call|>";var $i=a=>a<=127;function Vn(a){if(a.length===0)return!1;let e=a.charCodeAt(a.length-1);return e>=55296&&e<=56319}function Nr(a){let e=0;for(;e<a.length;){let n=a[e],i=0,r=0;if(n<=127)i=1,r=n;else if((n&224)===192){if(i=2,r=n&31,n<=193)return!1}else if((n&240)===224)i=3,r=n&15;else if((n&248)===240){if(i=4,r=n&7,n>244)return!1}else return!1;if(e+i>a.length)return!1;for(let t=1;t<i;t++){let s=a[e+t];if(s===void 0||(s&192)!==128)return!1;r=r<<6|s&63}if(i===2&&r<128||i===3&&r<2048||i===4&&r<65536||r>=55296&&r<=57343||r>1114111)return!1;e+=i}return!0}var Lr=new TextDecoder("utf8",{fatal:!1});function Ji(a){if(Nr(a))return Lr.decode(a)}function Yi(a,e){let n=Math.min(a.length,e.length);for(let i=0;i<n;i++)if(a[i]!==e[i])return a[i]-e[i];return a.length-e.length}function Xi(a){let e=0;return a.forEach(n=>{e=Math.max(e,n)}),e}function Wn(a){return a.replace(/[$()*+.?[\\\]^{|}]/g,"\\$&")}function Kn(a){let e=[...a].map(Wn).join("|");return new RegExp(`(${e})`)}var nn=new Uint8Array(0),fa=new TextDecoder("utf8"),Zi=class{mergeableBytePairRankCount;bytePairRankDecoder;bytePairNonUtfRankDecoder=new Map;bytePairNonUtfSortedEncoder;bytePairStringRankEncoder;tokenSplitRegex;specialTokensEncoder;specialTokensDecoder;specialTokenPatternRegex;textEncoder=new TextEncoder;mergeCache;mergeCacheSize;constructor({bytePairRankDecoder:a,specialTokensEncoder:e,tokenSplitRegex:n,mergeCacheSize:i=1e5}){this.bytePairRankDecoder=a,this.bytePairStringRankEncoder=new Map,this.mergeCacheSize=i,i>0&&(this.mergeCache=new Map),this.mergeableBytePairRankCount=Object.keys(a).length;let r=[];a.forEach((s,o)=>{if(typeof s=="string"){this.bytePairStringRankEncoder.set(s,o);return}let l=new Uint8Array(s);r.push([l,o]),this.bytePairNonUtfRankDecoder.set(o,l)}),this.bytePairNonUtfSortedEncoder=r.sort((s,o)=>Yi(s[0],o[0])),this.specialTokensEncoder=e??new Map,this.specialTokensDecoder=e?new Map([...e].map(([s,o])=>[o,s])):new Map,this.tokenSplitRegex=n;let t=[...this.specialTokensEncoder.keys()].map(Wn).join("|");try{this.specialTokenPatternRegex=new RegExp(t,"y")}catch{throw new Error("Invalid regular expression pattern.")}}setMergeCacheSize(a){this.mergeCacheSize===0&&a>0&&(this.mergeCache=new Map),this.mergeCacheSize=a,a===0&&(this.mergeCache=void 0)}clearMergeCache(){this.mergeCache?.clear()}*encodeNativeGenerator(a,e){let n=0,i=0;for(;;){let r=this.findNextSpecialToken(a,e,n),t=r?.[0],s=t??a.length,o=n===0&&s===a.length?a:a.slice(n,s);for(let[l]of o.matchAll(this.tokenSplitRegex)){let c=this.getBpeRankFromString(l);if(c!==void 0){i=1,yield[c];continue}let u=this.bytePairEncode(l);i=u.length,yield u}if(t!==void 0){let l=r[1],c=this.specialTokensEncoder.get(l);if(c===void 0)throw new Error(`Special token "${l}" is not in the special token encoder.`);yield[c],n=t+l.length,i=1}else break}return i}encodeNative(a,e){let n=0,i=[];for(;;){let r=this.findNextSpecialToken(a,e,n),t=r?.[0],s=t??a.length,o=n===0&&s===a.length?a:a.slice(n,s);for(let[l]of o.matchAll(this.tokenSplitRegex)){let c=this.getBpeRankFromString(l);if(c!==void 0){i.push(c);continue}let u=this.bytePairEncode(l);i.push(...u)}if(t!==void 0){let l=r[1],c=this.specialTokensEncoder.get(l);if(c===void 0)throw new Error(`Special token "${l}" is not in the special token encoder.`);i.push(c),n=t+l.length}else break}return i}countNative(a,e){let n=0,i=0;for(;;){let r=this.findNextSpecialToken(a,e,n),t=r?.[0],s=t??a.length,o=n===0&&s===a.length?a:a.slice(n,s);for(let[l]of o.matchAll(this.tokenSplitRegex)){if(this.getBpeRankFromString(l)!==void 0){i++;continue}let c=this.bytePairEncode(l);i+=c.length}if(t!==void 0){let l=r[1];if(this.specialTokensEncoder.get(l)===void 0)throw new Error(`Special token "${l}" is not in the special token encoder.`);i++,n=t+l.length}else break}return i}*decodeNativeGenerator(a){for(let e of a){let n=this.tryDecodeToken(e);n&&(yield n)}}decodeNative(a){let e="",n=nn;for(let i of a){let r=this.tryDecodeToken(i);if(r===void 0)throw new Error(`Token ${i} is not in the byte pair encoder.`);if(typeof r=="string")n!==nn&&(e+=fa.decode(n,{stream:!0}),n=nn),e+=r;else{let t=new Uint8Array(n.length+r.length);t.set(n),t.set(r,n.length),n=t}}return n!==nn&&(e+=fa.decode(n,{stream:!0})),e}async*decodeNativeAsyncIterable(a){for await(let e of a){let n=this.tryDecodeToken(e);n&&(yield n)}}getBpeRankFromString(a){return this.bytePairStringRankEncoder.get(a)}getBpeRankFromStringOrThrow(a){let e=this.getBpeRankFromString(a);if(e===void 0)throw new Error(`The byte-pair encoding does not contain a value for: ${a}`);return e}getBpeRankFromBytes(a){let e=Ji(a);if(e!==void 0)return this.getBpeRankFromString(e);let n=this.binarySearch(a);if(n!==-1)return this.bytePairNonUtfSortedEncoder[n][1]}getBpeRankFromBytesOrThrow(a){let e=this.getBpeRankFromBytes(a);if(e===void 0)throw new Error(`The byte-pair encoding does not contain a value for: ${a.toString()}`);return e}binarySearch(a){let e=0,n=this.bytePairNonUtfSortedEncoder.length-1;for(;e<=n;){let i=e+n>>>1,r=this.bytePairNonUtfSortedEncoder[i][0],t=0,s=Math.min(r.length,a.length);for(let o=0;o<s&&(t=r[o]-a[o],t===0);o++);if(t===0&&(t=r.length-a.length),t===0)return i;t<0?e=i+1:n=i-1}return-1}findNextSpecialToken(a,e,n){let i=n;for(;;){this.specialTokenPatternRegex.lastIndex=i;let r=this.specialTokenPatternRegex.exec(a);if(!r)return;let t=r[0];if(e?.has(t))return[r.index+i,t];i=r.index+i+1}}tryDecodeToken(a){let e=this.bytePairRankDecoder[a];if(typeof e=="string")return e;if(typeof e=="object"){let n=this.bytePairNonUtfRankDecoder.get(a);if(n)return n}return this.specialTokensDecoder.get(a)}addToMergeCache(a,e){if(this.mergeCache){if(this.mergeCache.size>=this.mergeCacheSize){let n=this.mergeCache.keys().next().value;this.mergeCache.delete(n)}this.mergeCache.set(a,e)}}bytePairEncode(a){if(a.length===1&&$i(a.codePointAt(0)))return[this.getBpeRankFromStringOrThrow(a)];if(this.mergeCache?.has(a)){let i=this.mergeCache.get(a);return this.mergeCache.delete(a),this.mergeCache.set(a,i),i}let e=this.textEncoder.encode(a),n=this.bytePairMerge(e);return this.addToMergeCache(a,n),n}bytePairMerge(a){let e=[],n=[],i=(t,s=e[t],o=e[t+2])=>{if(o===void 0)return Number.POSITIVE_INFINITY;let l=a.subarray(s,o);return this.getBpeRankFromBytes(l)??Number.POSITIVE_INFINITY};for(let t=0;t<=a.length;t++)e.push(t),t<a.length-1?n.push(i(t,t,t+2)):n.push(Number.POSITIVE_INFINITY);for(;e.length>1;){let t=Number.POSITIVE_INFINITY,s=-1;for(let o=0;o<n.length-1;o++){let l=n[o];l<t&&(t=l,s=o)}if(t===Number.POSITIVE_INFINITY||s===-1)break;e.splice(s+1,1),n.splice(s,1),n[s]=i(s),s>0&&(n[s-1]=i(s-1))}let r=[];for(let t=0;t<e.length-1;t++){let s=e[t],o=e[t+1],l=this.getBpeRankFromBytesOrThrow(a.subarray(s,o));r.push(l)}return r}};function Br(a,e){let n=0;if(a.role&&(n+=e(a.role)),a.content&&(n+=e(a.content)),a.name&&(n+=e(a.name)+1),a.function_call){let{name:i,arguments:r}=a.function_call;i&&(n+=e(i)),r&&(n+=e(r)),n+=3}return n+=3,a.role==="function"&&(n-=2),n}function et(a,e,n){if(!a.properties)return"";let i=[],r=new Set(a.required??[]),t=" ".repeat(e);for(let[s,o]of Object.entries(a.properties)){o.description&&e<2&&i.push(`${t}// ${o.description}`);let l=r.has(s),c=n(o,e);i.push(`${t}${s}${l?"":"?"}: ${c},`)}return i.join(`
3
- `)}function $n(a,e){switch(a.type){case"string":return a.enum?.map(n=>JSON.stringify(n)).join(" | ")??"string";case"integer":case"number":return a.enum?.map(n=>`${n}`).join(" | ")??"number";case"boolean":return"boolean";case"null":return"null";case"array":return a.items?`${$n(a.items,e)}[]`:"any[]";case"object":return`{
4
- ${et(a,e+2,$n)}
5
- ${" ".repeat(e)}}`;default:return"any"}}function Fr(a){let e=["namespace functions {",""];for(let n of a){n.description&&e.push(`// ${n.description}`);let{parameters:i}=n,r=i?.properties;if(!i||!r||Object.keys(r).length===0)e.push(`type ${n.name} = () => any;`);else{e.push(`type ${n.name} = (_: {`);let t=et(i,0,$n);t.length>0&&e.push(t),e.push("}) => any;")}e.push("")}return e.push("} // namespace functions"),e.join(`
6
- `)}function Gr(a,e){let n=e(Fr(a));return n+=9,n}function qr(a,e,n){return!e||n||a.role!=="system"||!a.content||a.content.endsWith(`
2
+ import{readFileSync as us}from"node:fs";import{createHash as os}from"node:crypto";var fe=()=>({requests:0,errors:0,replayed:0,inputTokens:0,inputTokensBefore:0,outputTokens:0,outputTokensAvoided:0,cachedInputTokens:0,reasoningTokens:0,savedInputTokens:0,costUsd:0,costBeforeUsd:0,pricedRequests:0,checks:0,checksMatched:0,checkCostUsd:0});function ot(a,e){let n=a.pricing,i=n?.longContext,r=a.priceTier??(i?{aboveInputTokens:i.aboveTokens,inputPerMTok:i.inputPerMTok,outputPerMTok:i.outputPerMTok}:void 0);if(!n||!r||e<=r.aboveInputTokens)return n;let t=r.inputPerMTok/n.inputPerMTok;return{inputPerMTok:r.inputPerMTok,outputPerMTok:r.outputPerMTok,cachedInputPerMTok:n.cachedInputPerMTok!==void 0?n.cachedInputPerMTok*t:void 0}}function ca(a,e){let n=ot(a,e.inputTokens??0);if(!n)return 0;let i=e.cachedInputTokens??0,r=e.cacheWriteTokens??0,t=Math.max(0,(e.inputTokens??0)-i-r),s=a.family==="anthropic"?n.inputPerMTok*1.25:n.inputPerMTok;return(t*n.inputPerMTok+i*(n.cachedInputPerMTok??n.inputPerMTok)+r*s+(e.outputTokens??0)*n.outputPerMTok)/1e6}function pn(a,e,n){let i=ot(a,(e.inputTokens??0)+n);return i?(((e.inputTokens??0)+n)*i.inputPerMTok+(e.outputTokens??0)*i.outputPerMTok)/1e6:0}function ja(a,e){a.requests++,e.status>=400&&a.errors++,e.profile.pricing&&a.pricedRequests++;let n={...e.usage,inputTokens:e.usage.inputTokens??e.estimatedInput};if(e.replayed){a.replayed++,a.inputTokensBefore+=n.inputTokens,a.savedInputTokens+=n.inputTokens,a.outputTokensAvoided+=n.outputTokens??0,a.costBeforeUsd+=pn(e.profile,n,0);return}a.inputTokens+=n.inputTokens,a.inputTokensBefore+=n.inputTokens+e.savedInput,a.outputTokens+=n.outputTokens??0,a.cachedInputTokens+=n.cachedInputTokens??0,a.reasoningTokens+=n.reasoningTokens??0,a.savedInputTokens+=e.savedInput,a.costUsd+=ca(e.profile,n)*(e.priceFactor??1),a.costBeforeUsd+=pn(e.profile,n,e.savedInput)}var ss=["app","agent","model"],gn=class{rows=new Map;started=new Date().toISOString();row(e,n,i){let r=[e,n,i].join("\0"),t=this.rows.get(r);return t||this.rows.set(r,t=fe()),t}record(e){ja(this.row(e.app,e.agent,e.profile.id),e)}recordCheck(e,n,i,r,t,s=!0){let o=this.row(e,n,i.id);s&&o.checks++,s&&r&&o.checksMatched++,o.checkCostUsd+=t}snapshot(){return new Map([...this.rows].map(([e,n])=>[e,{...n}]))}grouped(e,n=this.rows){let i=new Map;for(let[r,t]of n){let s=r.split("\0"),o=e.map(c=>s[ss.indexOf(c)]).join("\0"),l=i.get(o)??fe();for(let c of Object.keys(l))l[c]+=t[c];i.set(o,l)}return[...i].map(([r,t])=>({...Object.fromEntries(e.map((s,o)=>[s,r.split("\0")[o]])),...Sa(t)}))}detail(e=this.rows){return this.grouped(["app","agent","model"],e)}json(e=this.rows,n=this.started){let[i]=this.grouped([],e);return{since:n,total:i??Sa(fe()),byTeam:this.grouped(["app"],e),byAgent:this.grouped(["app","agent"],e),byModel:this.grouped(["model"],e),byAppAndModel:this.grouped(["app","model"],e)}}prometheus(e){let n=[["requests","token_lens_requests_total","Requests proxied"],["errors","token_lens_errors_total","Requests that ended in an error status"],["replayed","token_lens_replayed_total","Identical requests answered from the gateway's copy"],["inputTokens","token_lens_input_tokens_total","Input tokens sent upstream"],["inputTokensBefore","token_lens_input_tokens_before_total","Input tokens the same calls would have sent without Token Lens"],["outputTokens","token_lens_output_tokens_total","Output tokens generated"],["cachedInputTokens","token_lens_cached_input_tokens_total","Input tokens served from the provider's prompt cache"],["reasoningTokens","token_lens_reasoning_tokens_total","Hidden reasoning tokens"],["savedInputTokens","token_lens_saved_input_tokens_total","Input tokens removed by Token Lens"],["costUsd","token_lens_cost_usd_total","Spend after Token Lens, for models with pricing"],["costBeforeUsd","token_lens_cost_before_usd_total","Spend the same calls would have cost without Token Lens"],["checks","token_lens_output_checks_total","Output checks run (optimized vs original answer)"],["checksMatched","token_lens_output_checks_matched_total","Output checks where the answers matched"],["checkCostUsd","token_lens_output_check_cost_usd_total","Spend on output checks"]],i=t=>t.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),r=[];for(let[t,s,o]of n){r.push(`# HELP ${s} ${o}`,`# TYPE ${s} counter`);for(let[l,c]of this.rows){let[u,g,h]=l.split("\0");e!==void 0&&u!==e||r.push(`${s}{app="${i(u)}",agent="${i(g)}",model="${i(h)}"} ${c[t]}`)}}return r.join(`
3
+ `)+`
4
+ `}},Ze=(a,e=6)=>Math.round(a*10**e)/10**e;function Sa(a){let e=a.inputTokensBefore-a.inputTokens+a.outputTokensAvoided,n=a.costBeforeUsd-a.costUsd;return{...a,costUsd:Ze(a.costUsd),costBeforeUsd:Ze(a.costBeforeUsd),checkCostUsd:Ze(a.checkCostUsd),savedTokens:e,savedTokensPct:a.inputTokensBefore+a.outputTokens+a.outputTokensAvoided?Ze(e/(a.inputTokensBefore+a.outputTokens+a.outputTokensAvoided)*100,1):0,savedUsd:Ze(n),savedUsdPct:a.costBeforeUsd?Ze(n/a.costBeforeUsd*100,1):0,netSavedUsd:Ze(n-a.checkCostUsd),outputUnchangedPct:a.checks?Ze(a.checksMatched/a.checks*100,1):null,unpricedRequests:a.requests-a.pricedRequests}}var ct={fromBody:!1,hashIds:!1,maxCustomers:1e5,budget:{},plans:{},teamBudgets:{}};function lt(a,e){let n=e.toISOString();return a==="day"?`d${n.slice(0,10)}`:`m${n.slice(0,7)}`}var ut=a=>(a==="day"?2:32)*86400,dt=a=>`h:${os("sha256").update(a).digest("hex").slice(0,16)}`;function hn(a){return typeof a!="string"?void 0:a.replace(/[\u0000-\u001f\u007f]/g,"").trim().slice(0,128)||void 0}function mt(a,e,n){let i=hn(a)??(n.fromBody?hn(e?.safety_identifier)??hn(e?.user)??hn(e?.metadata?.user_id):void 0);if(i)return n.hashIds?dt(i):i}var pt=(a,e)=>e.hashIds?dt(a):a,bn=[["dailyUsd","day","usd"],["monthlyUsd","month","usd"],["dailyTokens","day","tokens"],["monthlyTokens","month","tokens"]],ls={"daily-usd":"dailyUsd","monthly-usd":"monthlyUsd","daily-tokens":"dailyTokens","monthly-tokens":"monthlyTokens"},cs=a=>typeof a=="number"&&Number.isFinite(a)&&a>=0;function fn(a){let e={};for(let[n]of bn)cs(a?.[n])&&(e[n]=a[n]);return e}var _a=class extends Error{};function ii(a,e,n){if(e&&!a.plans[e])throw new _a(`Unknown plan "${e}". Plans in this gateway's config: ${Object.keys(a.plans).join(", ")||"none"}.`);let i={};for(let[r,t]of Object.entries(ls)){let s=n(`x-token-lens-customer-${r}`);s!==void 0&&s!==""&&(i[t]=Number(s))}return{...fn(a.budget),...fn(e?a.plans[e]:void 0),...fn(i)}}function ti(a,e){return fn(a.teamBudgets[e]??a.teamBudgets["*"])}var ri=a=>bn.some(([e])=>a[e]!==void 0),ni="",Oa=(...a)=>a.join("\0"),kn=class{constructor(e){this.maxCustomers=e}maxCustomers;rows=new Map;local=new Map;flushed=new Map;shared=new Map;periods="";prune(e){let n=lt("day",e),i=lt("month",e),r=n+i;if(r!==this.periods){this.periods=r;for(let t of[this.local,this.flushed,this.shared])for(let s of t.keys()){let o=s.slice(0,s.indexOf("\0"));o!==n&&o!==i&&t.delete(s)}}return[n,i]}record(e,n,i,r=new Date){let t=fe();if(ja(t,i),n){let o=Oa(e,n),l=this.rows.get(o);l?this.rows.delete(o):l={totals:fe(),firstSeen:r.toISOString(),lastSeen:""},l.lastSeen=r.toISOString();for(let c of Object.keys(t))l.totals[c]+=t[c];for(this.rows.set(o,l);this.rows.size>this.maxCustomers;)this.rows.delete(this.rows.keys().next().value)}if(i.status>=400||i.replayed)return;let s={usd:t.costUsd,tokens:t.inputTokens+t.outputTokens};if(!(!s.usd&&!s.tokens))for(let o of this.prune(r))for(let l of n?[n,ni]:[ni]){let c=Oa(o,e,l),u=this.local.get(c)??{usd:0,tokens:0};u.usd+=s.usd,u.tokens+=s.tokens,this.local.set(c,u)}}spent(e,n,i,r=new Date){let[t,s]=this.prune(r),o=Oa(i==="day"?t:s,e,n??ni),l=this.local.get(o),c=this.flushed.get(o),u=this.shared.get(o);return{usd:(u?.usd??0)+(l?.usd??0)-(c?.usd??0),tokens:(u?.tokens??0)+(l?.tokens??0)-(c?.tokens??0)}}over(e,n,i,r=new Date){let t=[["team",i.team,void 0]];n&&t.unshift(["customer",i.customer,n]);for(let[s,o,l]of t)for(let[c,u,g]of bn){let h=o[c];if(h===void 0)continue;let y=this.spent(e,l,u,r)[g];if(y>=h)return{who:s,limit:c,cap:h,spent:y}}}remaining(e,n,i,r=new Date){let t={},s=[[i.team,void 0]];n&&s.push([i.customer,n]);for(let[o,l]of s)for(let[c,u,g]of bn){let h=o[c];if(h===void 0)continue;let y=Math.max(0,h-this.spent(e,l,u,r)[g]);t[g]=Math.min(t[g]??1/0,y)}return t}snapshot(){return new Map([...this.rows].map(([e,n])=>[e,{...n.totals}]))}lastSeen(e,n){return this.rows.get(Oa(e,n))?.lastSeen}list(e,n=this.snapshot(),i=new Date){let r=[];for(let[t,s]of n){let[o,l]=t.split("\0");e!==void 0&&o!==e||r.push(this.view(o,l,s,i))}return r.sort((t,s)=>s.costBeforeUsd-t.costBeforeUsd)}view(e,n,i=fe(),r=new Date){let t=this.spent(e,n,"day",r),s=this.spent(e,n,"month",r),o=l=>Math.round(l*1e6)/1e6;return{team:e,customer:n,...Sa(i),lastSeen:this.lastSeen(e,n),spentToday:{usd:o(t.usd),tokens:t.tokens},spentThisMonth:{usd:o(s.usd),tokens:s.tokens}}}takeSpendDeltas(e=new Date){this.prune(e);let n=[];for(let[i,r]of this.local){let t=this.flushed.get(i)??{usd:0,tokens:0},[s,...o]=i.split("\0"),l=o.join("\0");r.usd!==t.usd&&n.push({period:s,field:`${l}\0usd`,by:r.usd-t.usd}),r.tokens!==t.tokens&&n.push({period:s,field:`${l}\0tokens`,by:r.tokens-t.tokens}),this.flushed.set(i,{...r})}return n}setSharedSpend(e,n){for(let i of[...this.shared.keys()])i.startsWith(`${e}\0`)&&this.shared.delete(i);for(let[i,r]of Object.entries(n)){let t=i.split("\0"),s=t.pop();if(s!=="usd"&&s!=="tokens")continue;let o=Oa(e,...t),l=this.shared.get(o)??{usd:0,tokens:0};l[s]=Number(r),this.shared.set(o,l)}}currentPeriods(e=new Date){return this.prune(e)}};function gt(a){let e=["team","customer","requests","inputTokensBefore","inputTokens","outputTokens","savedTokens","savedTokensPct","costBeforeUsd","costUsd","savedUsd","savedUsdPct","spentTodayUsd","spentThisMonthUsd","lastSeen"],n=r=>{let t=r==null?"":String(r),s=/^[=+\-@]/.test(t)&&!/^-?\d/.test(t)?`'${t}`:t;return/[",\n]/.test(s)?`"${s.replace(/"/g,'""')}"`:s},i=[e.join(",")];for(let r of a)i.push([r.team,r.customer,r.requests,r.inputTokensBefore,r.inputTokens,r.outputTokens,r.savedTokens,r.savedTokensPct,r.costBeforeUsd,r.costUsd,r.savedUsd,r.savedUsdPct,r.spentToday.usd,r.spentThisMonth.usd,r.lastSeen].map(n).join(","));return i.join(`
5
+ `)+`
6
+ `}var ua={port:8080,host:"0.0.0.0",mode:"optimize",level:"auto",safe:{prompt:!0,minifyJson:!0,collapseRepeats:!0,dedupeToolOutputs:!0,dedupePassages:!0,dedupeImages:!0,promptCaching:!0,dedupeRetries:!0,cacheEmbeddings:!0},optIn:{elideOldToolOutputs:!1,lazyTools:!1,trimToolFields:!1,compactJson:!1,parkToolOutputs:!1,flex:!1,warmCache:!1},verify:{sampleRate:.05,minSimilarity:.8,maxShareOfSavings:.2,freeChecks:5,probation:5},runBudget:{},batch:{flushSeconds:60,pollSeconds:60,maxRequests:1e3,discount:.5},flexDiscount:.5,embeddingsCacheMB:256,priceTiers:[],storage:{keyPrefix:"token-lens:",flushSeconds:10,runDays:7},retryWindowSeconds:120,blockOverContext:!1,upstreams:{},routes:[],models:[],clientKeys:[],customers:ct,isolateTeams:!1,maxBodyBytes:32*1024*1024,maxRuns:2e3,logRequests:!0,reportToolArgs:!1};function si(a,e){if(typeof a=="string"&&a.startsWith("env:")){let n=a.slice(4);return e[n]??""}return Array.isArray(a)?a.map(n=>si(n,e)):a&&typeof a=="object"?Object.fromEntries(Object.entries(a).map(([n,i])=>[n,si(i,e)])):a}var ht=[{name:"openai",type:"openai",key:["OPENAI_API_KEY"],baseUrlEnv:"OPENAI_BASE_URL",baseUrl:"https://api.openai.com/v1",models:["gpt-*","chatgpt-*","o1*","o3*","o4*"]},{name:"anthropic",type:"anthropic",key:["ANTHROPIC_API_KEY"],baseUrlEnv:"ANTHROPIC_BASE_URL",baseUrl:"https://api.anthropic.com",models:["claude-*"]},{name:"gemini",type:"openai",key:["GEMINI_API_KEY","GOOGLE_API_KEY"],baseUrl:"https://generativelanguage.googleapis.com/v1beta/openai",models:["gemini-*","gemma-*"]},{name:"mistral",type:"openai",key:["MISTRAL_API_KEY"],baseUrl:"https://api.mistral.ai/v1",models:["mistral-*","magistral-*","codestral-*","devstral-*","ministral-*","pixtral-*","open-mistral-*","open-mixtral-*"]},{name:"deepseek",type:"openai",key:["DEEPSEEK_API_KEY"],baseUrl:"https://api.deepseek.com/v1",models:["deepseek-*"]},{name:"xai",type:"openai",key:["XAI_API_KEY"],baseUrl:"https://api.x.ai/v1",models:["grok-*"]},{name:"moonshot",type:"openai",key:["MOONSHOT_API_KEY"],baseUrl:"https://api.moonshot.ai/v1",models:["kimi-*","moonshot-*"]},{name:"qwen",type:"openai",key:["DASHSCOPE_API_KEY"],baseUrl:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",models:["qwen*","qwq-*"]},{name:"cohere",type:"openai",key:["COHERE_API_KEY"],baseUrl:"https://api.cohere.ai/compatibility/v1",models:["command-*"]},{name:"perplexity",type:"openai",key:["PERPLEXITY_API_KEY"],baseUrl:"https://api.perplexity.ai",models:["sonar*"]},{name:"openrouter",type:"openai",key:["OPENROUTER_API_KEY"],baseUrl:"https://openrouter.ai/api/v1",models:["*/*"]},{name:"groq",type:"openai",key:["GROQ_API_KEY"],baseUrl:"https://api.groq.com/openai/v1"},{name:"together",type:"openai",key:["TOGETHER_API_KEY"],baseUrl:"https://api.together.xyz/v1"},{name:"fireworks",type:"openai",key:["FIREWORKS_API_KEY"],baseUrl:"https://api.fireworks.ai/inference/v1"},{name:"cerebras",type:"openai",key:["CEREBRAS_API_KEY"],baseUrl:"https://api.cerebras.ai/v1"},{name:"azure",type:"openai",key:["AZURE_OPENAI_API_KEY"],baseUrlEnv:"AZURE_OPENAI_ENDPOINT",authHeader:"api-key"},{name:"ollama",type:"openai",baseUrlEnv:"OLLAMA_BASE_URL"},{name:"lmstudio",type:"openai",baseUrlEnv:"LMSTUDIO_BASE_URL"}];function ds(a){let e={};for(let n of ht){let i=n.key?.map(t=>a[t]).find(Boolean),r=n.baseUrlEnv&&a[n.baseUrlEnv]||void 0;if(!(!i&&!r)){if(n.name==="azure"){if(!r)continue;r=r.replace(/\/+$/,""),/\/openai\/v1$/.test(r)||(r+="/openai/v1")}(n.name==="ollama"||n.name==="lmstudio")&&r&&!/\/v1\/?$/.test(r)&&(r=r.replace(/\/+$/,"")+"/v1"),e[n.name]={type:n.type,baseUrl:r??n.baseUrl,...i?{apiKey:i}:{},...n.authHeader?{authHeader:n.authHeader}:{}}}}return e}function ms(a={},e={}){let n=si(a,e),i={...ua,...n,safe:{...ua.safe,...n.safe},optIn:{...ua.optIn,...n.optIn},verify:{...ua.verify,...n.verify},batch:{...ua.batch,...n.batch},storage:{...ua.storage,...n.storage},customers:{...ua.customers,...n.customers},upstreams:{...ds(e),...n.upstreams}};for(let r of ht)if(i.upstreams[r.name]&&!n.upstreams?.[r.name])for(let t of r.models??[])i.routes=[...i.routes,{model:t,upstream:r.name}];if(e.TOKEN_LENS_DEFAULT_UPSTREAM&&(i.defaultUpstream=e.TOKEN_LENS_DEFAULT_UPSTREAM),e.TOKEN_LENS_ISOLATE_TEAMS&&(i.isolateTeams=e.TOKEN_LENS_ISOLATE_TEAMS==="true"||e.TOKEN_LENS_ISOLATE_TEAMS==="1"),e.PORT&&(i.port=Number(e.PORT)),e.TOKEN_LENS_MODE&&(i.mode=e.TOKEN_LENS_MODE),e.TOKEN_LENS_VERIFY_RATE&&(i.verify.sampleRate=Number(e.TOKEN_LENS_VERIFY_RATE)),e.TOKEN_LENS_ADMIN_KEY&&(i.adminKey=e.TOKEN_LENS_ADMIN_KEY),e.TOKEN_LENS_REDIS_URL&&(i.storage.redisUrl=e.TOKEN_LENS_REDIS_URL),e.TOKEN_LENS_STORAGE_FILE&&(i.storage.file=e.TOKEN_LENS_STORAGE_FILE),e.TOKEN_LENS_CLIENT_KEYS&&(i.clientKeys=[...i.clientKeys,...e.TOKEN_LENS_CLIENT_KEYS.split(",").map(r=>r.trim()).filter(Boolean).map((r,t)=>{let[s,o]=r.includes(":")?r.split(/:(.*)/s):[`client-${t+1}`,r];return{name:s,key:o}})]),i.clientKeys=i.clientKeys.filter(r=>r.key),i.isolateTeams&&!i.clientKeys.length)throw new Error("isolateTeams needs client keys (clientKeys or TOKEN_LENS_CLIENT_KEYS): without them every caller is the same team.");for(let[r,t]of Object.entries(i.upstreams)){if(t.type!=="openai"&&t.type!=="anthropic")throw new Error(`Upstream "${r}": type must be "openai" or "anthropic".`);if(!t.baseUrl)throw new Error(`Upstream "${r}" needs a baseUrl.`);t.baseUrl=t.baseUrl.replace(/\/+$/,""),t.apiKey||delete t.apiKey}for(let r of i.routes)if(!i.upstreams[r.upstream])throw new Error(`Route "${r.model}" points at unknown upstream "${r.upstream}".`);if(i.defaultUpstream&&!i.upstreams[i.defaultUpstream])throw new Error(`defaultUpstream "${i.defaultUpstream}" is not defined.`);return i}function ft(a=process.env){let e=a.TOKEN_LENS_CONFIG,n=e?JSON.parse(us(e,"utf8")):{};return ms(n,a)}import{createServer as el}from"node:http";import{timingSafeEqual as al}from"node:crypto";var Ea=a=>a.toLocaleString("en-US");function Da(a){let{profile:e,task:n,signals:i,promptTokens:r,usage:t,text:s}=a,o=[];if(n==="coding"&&i.pastedTokens>1500&&o.push({id:"paste-less-code",text:`About ${Ea(i.pastedTokens)} tokens of pasted code. Paste only the functions involved.`,saves:"input"}),n==="debugging"&&i.hasLogs&&i.pastedTokens>800&&o.push({id:"trim-logs",text:"Long log pasted. The first error and its stack are usually enough; Optimize collapses repeated lines and library frames.",saves:"input"}),n==="analysis"&&i.hasData&&i.pastedTokens>2e3&&o.push({id:"sample-data",text:"Large table pasted. The header plus ~20 sample rows and a description of the rest is usually enough; or attach the file instead.",saves:"input"}),i.pastedTokens>t.window*.4&&o.push({id:"split-material",text:`The pasted material is ${Math.round(i.pastedTokens/t.window*100)}% of ${e.label}'s context. Split it into parts or paste only what's needed.`,saves:"input"}),e.family==="anthropic"&&i.pastedTokens>300&&!/<[a-z][\w-]*>/i.test(s))for(let u of e.notes??[])o.push({id:"family-note",text:u,saves:"input"});t.zone==="hot"||t.zone==="full"?o.push({id:"handoff",text:`This chat fills about ${Math.round(t.ratio*100)}% of ${e.label}'s context. Older messages will be dropped or compacted soon. Hand off to a new chat.`,saves:"input"}):(t.longChat||t.zone==="warm")&&o.push({id:"handoff",text:`Every new message re-reads about ${Ea(t.conversationTokens)} tokens of history. A handoff brief and a new chat cut that.`,saves:"input"});let l=e.pricing?.longContext,c=t.conversationTokens+r;return l&&e.pricing&&c>=l.aboveTokens*.85&&o.push({id:"price-threshold",text:c>l.aboveTokens?`This message reads \u2248${Ea(c)} tokens, past ${Ea(l.aboveTokens)}, so ${e.label} bills all of it at $${l.inputPerMTok}/M instead of $${e.pricing.inputPerMTok}/M. Continuing from a handoff brief in a new chat brings it back under.`:`This chat is \u2248${Ea(c)} tokens; past ${Ea(l.aboveTokens)}, ${e.label} bills every message at $${l.inputPerMTok}/M instead of $${e.pricing.inputPerMTok}/M. Hand off to a new chat before then.`,saves:"input"}),o}function Na(a,e,n,i){let r=i&&i>0?i:n.contextWindow,t=(a+e)/r,s=t>=.95?"full":t>=.8?"hot":t>=.5?"warm":"ok";return{conversationTokens:a,promptTokens:e,window:r,ratio:t,zone:s,longChat:a>=4e4}}function bt(a,e){return a!=="auto"?a:e.zone==="hot"||e.zone==="full"?"aggressive":"balanced"}var ps={coding:"the files and functions involved, the current state of the code (only the parts still changing, verbatim), and what is left to build",debugging:"the bug, what has been ruled out, the most likely cause, and the exact error message",writing:"the audience, tone, the current outline, and any passages I approved (verbatim)",editing:"the style rules we settled on and which parts are already done",analysis:"the dataset's shape, the findings so far with their numbers, and the next questions",research:"the question, the answers found so far with their sources, and what is still open"};function kt(a){return["Write a handoff brief of this conversation that I can paste into a new chat to continue without the history.",`Cover: ${ps[a]??"the goal, the decisions made, and the current state"}; plus open questions and my preferences.`,"Use terse bullets, under 250 words, and nothing else."].join(" ")}var de="<|endoftext|>",Be="<|fim_prefix|>",Fe="<|fim_middle|>",Ge="<|fim_suffix|>",da="<|im_start|>",ma="<|im_end|>",qe="<|im_sep|>",Ue="<|endofprompt|>",oi="<|startoftext|>",La="<|start|>",Ba="<|end|>",Fa="<|message|>",Ga="<|channel|>",qa="<|return|>",Ua="<|constrain|>",Ha="<|call|>";var yt=a=>a<=127;function li(a){if(a.length===0)return!1;let e=a.charCodeAt(a.length-1);return e>=55296&&e<=56319}function gs(a){let e=0;for(;e<a.length;){let n=a[e],i=0,r=0;if(n<=127)i=1,r=n;else if((n&224)===192){if(i=2,r=n&31,n<=193)return!1}else if((n&240)===224)i=3,r=n&15;else if((n&248)===240){if(i=4,r=n&7,n>244)return!1}else return!1;if(e+i>a.length)return!1;for(let t=1;t<i;t++){let s=a[e+t];if(s===void 0||(s&192)!==128)return!1;r=r<<6|s&63}if(i===2&&r<128||i===3&&r<2048||i===4&&r<65536||r>=55296&&r<=57343||r>1114111)return!1;e+=i}return!0}var hs=new TextDecoder("utf8",{fatal:!1});function vt(a){if(gs(a))return hs.decode(a)}function wt(a,e){let n=Math.min(a.length,e.length);for(let i=0;i<n;i++)if(a[i]!==e[i])return a[i]-e[i];return a.length-e.length}function St(a){let e=0;return a.forEach(n=>{e=Math.max(e,n)}),e}function ci(a){return a.replace(/[$()*+.?[\\\]^{|}]/g,"\\$&")}function ui(a){let e=[...a].map(ci).join("|");return new RegExp(`(${e})`)}var yn=new Uint8Array(0),Aa=new TextDecoder("utf8"),Et=class{mergeableBytePairRankCount;bytePairRankDecoder;bytePairNonUtfRankDecoder=new Map;bytePairNonUtfSortedEncoder;bytePairStringRankEncoder;tokenSplitRegex;specialTokensEncoder;specialTokensDecoder;specialTokenPatternRegex;textEncoder=new TextEncoder;mergeCache;mergeCacheSize;constructor({bytePairRankDecoder:a,specialTokensEncoder:e,tokenSplitRegex:n,mergeCacheSize:i=1e5}){this.bytePairRankDecoder=a,this.bytePairStringRankEncoder=new Map,this.mergeCacheSize=i,i>0&&(this.mergeCache=new Map),this.mergeableBytePairRankCount=Object.keys(a).length;let r=[];a.forEach((s,o)=>{if(typeof s=="string"){this.bytePairStringRankEncoder.set(s,o);return}let l=new Uint8Array(s);r.push([l,o]),this.bytePairNonUtfRankDecoder.set(o,l)}),this.bytePairNonUtfSortedEncoder=r.sort((s,o)=>wt(s[0],o[0])),this.specialTokensEncoder=e??new Map,this.specialTokensDecoder=e?new Map([...e].map(([s,o])=>[o,s])):new Map,this.tokenSplitRegex=n;let t=[...this.specialTokensEncoder.keys()].map(ci).join("|");try{this.specialTokenPatternRegex=new RegExp(t,"y")}catch{throw new Error("Invalid regular expression pattern.")}}setMergeCacheSize(a){this.mergeCacheSize===0&&a>0&&(this.mergeCache=new Map),this.mergeCacheSize=a,a===0&&(this.mergeCache=void 0)}clearMergeCache(){this.mergeCache?.clear()}*encodeNativeGenerator(a,e){let n=0,i=0;for(;;){let r=this.findNextSpecialToken(a,e,n),t=r?.[0],s=t??a.length,o=n===0&&s===a.length?a:a.slice(n,s);for(let[l]of o.matchAll(this.tokenSplitRegex)){let c=this.getBpeRankFromString(l);if(c!==void 0){i=1,yield[c];continue}let u=this.bytePairEncode(l);i=u.length,yield u}if(t!==void 0){let l=r[1],c=this.specialTokensEncoder.get(l);if(c===void 0)throw new Error(`Special token "${l}" is not in the special token encoder.`);yield[c],n=t+l.length,i=1}else break}return i}encodeNative(a,e){let n=0,i=[];for(;;){let r=this.findNextSpecialToken(a,e,n),t=r?.[0],s=t??a.length,o=n===0&&s===a.length?a:a.slice(n,s);for(let[l]of o.matchAll(this.tokenSplitRegex)){let c=this.getBpeRankFromString(l);if(c!==void 0){i.push(c);continue}let u=this.bytePairEncode(l);i.push(...u)}if(t!==void 0){let l=r[1],c=this.specialTokensEncoder.get(l);if(c===void 0)throw new Error(`Special token "${l}" is not in the special token encoder.`);i.push(c),n=t+l.length}else break}return i}countNative(a,e){let n=0,i=0;for(;;){let r=this.findNextSpecialToken(a,e,n),t=r?.[0],s=t??a.length,o=n===0&&s===a.length?a:a.slice(n,s);for(let[l]of o.matchAll(this.tokenSplitRegex)){if(this.getBpeRankFromString(l)!==void 0){i++;continue}let c=this.bytePairEncode(l);i+=c.length}if(t!==void 0){let l=r[1];if(this.specialTokensEncoder.get(l)===void 0)throw new Error(`Special token "${l}" is not in the special token encoder.`);i++,n=t+l.length}else break}return i}*decodeNativeGenerator(a){for(let e of a){let n=this.tryDecodeToken(e);n&&(yield n)}}decodeNative(a){let e="",n=yn;for(let i of a){let r=this.tryDecodeToken(i);if(r===void 0)throw new Error(`Token ${i} is not in the byte pair encoder.`);if(typeof r=="string")n!==yn&&(e+=Aa.decode(n,{stream:!0}),n=yn),e+=r;else{let t=new Uint8Array(n.length+r.length);t.set(n),t.set(r,n.length),n=t}}return n!==yn&&(e+=Aa.decode(n,{stream:!0})),e}async*decodeNativeAsyncIterable(a){for await(let e of a){let n=this.tryDecodeToken(e);n&&(yield n)}}getBpeRankFromString(a){return this.bytePairStringRankEncoder.get(a)}getBpeRankFromStringOrThrow(a){let e=this.getBpeRankFromString(a);if(e===void 0)throw new Error(`The byte-pair encoding does not contain a value for: ${a}`);return e}getBpeRankFromBytes(a){let e=vt(a);if(e!==void 0)return this.getBpeRankFromString(e);let n=this.binarySearch(a);if(n!==-1)return this.bytePairNonUtfSortedEncoder[n][1]}getBpeRankFromBytesOrThrow(a){let e=this.getBpeRankFromBytes(a);if(e===void 0)throw new Error(`The byte-pair encoding does not contain a value for: ${a.toString()}`);return e}binarySearch(a){let e=0,n=this.bytePairNonUtfSortedEncoder.length-1;for(;e<=n;){let i=e+n>>>1,r=this.bytePairNonUtfSortedEncoder[i][0],t=0,s=Math.min(r.length,a.length);for(let o=0;o<s&&(t=r[o]-a[o],t===0);o++);if(t===0&&(t=r.length-a.length),t===0)return i;t<0?e=i+1:n=i-1}return-1}findNextSpecialToken(a,e,n){let i=n;for(;;){this.specialTokenPatternRegex.lastIndex=i;let r=this.specialTokenPatternRegex.exec(a);if(!r)return;let t=r[0];if(e?.has(t))return[r.index+i,t];i=r.index+i+1}}tryDecodeToken(a){let e=this.bytePairRankDecoder[a];if(typeof e=="string")return e;if(typeof e=="object"){let n=this.bytePairNonUtfRankDecoder.get(a);if(n)return n}return this.specialTokensDecoder.get(a)}addToMergeCache(a,e){if(this.mergeCache){if(this.mergeCache.size>=this.mergeCacheSize){let n=this.mergeCache.keys().next().value;this.mergeCache.delete(n)}this.mergeCache.set(a,e)}}bytePairEncode(a){if(a.length===1&&yt(a.codePointAt(0)))return[this.getBpeRankFromStringOrThrow(a)];if(this.mergeCache?.has(a)){let i=this.mergeCache.get(a);return this.mergeCache.delete(a),this.mergeCache.set(a,i),i}let e=this.textEncoder.encode(a),n=this.bytePairMerge(e);return this.addToMergeCache(a,n),n}bytePairMerge(a){let e=[],n=[],i=(t,s=e[t],o=e[t+2])=>{if(o===void 0)return Number.POSITIVE_INFINITY;let l=a.subarray(s,o);return this.getBpeRankFromBytes(l)??Number.POSITIVE_INFINITY};for(let t=0;t<=a.length;t++)e.push(t),t<a.length-1?n.push(i(t,t,t+2)):n.push(Number.POSITIVE_INFINITY);for(;e.length>1;){let t=Number.POSITIVE_INFINITY,s=-1;for(let o=0;o<n.length-1;o++){let l=n[o];l<t&&(t=l,s=o)}if(t===Number.POSITIVE_INFINITY||s===-1)break;e.splice(s+1,1),n.splice(s,1),n[s]=i(s),s>0&&(n[s-1]=i(s-1))}let r=[];for(let t=0;t<e.length-1;t++){let s=e[t],o=e[t+1],l=this.getBpeRankFromBytesOrThrow(a.subarray(s,o));r.push(l)}return r}};function fs(a,e){let n=0;if(a.role&&(n+=e(a.role)),a.content&&(n+=e(a.content)),a.name&&(n+=e(a.name)+1),a.function_call){let{name:i,arguments:r}=a.function_call;i&&(n+=e(i)),r&&(n+=e(r)),n+=3}return n+=3,a.role==="function"&&(n-=2),n}function At(a,e,n){if(!a.properties)return"";let i=[],r=new Set(a.required??[]),t=" ".repeat(e);for(let[s,o]of Object.entries(a.properties)){o.description&&e<2&&i.push(`${t}// ${o.description}`);let l=r.has(s),c=n(o,e);i.push(`${t}${s}${l?"":"?"}: ${c},`)}return i.join(`
7
+ `)}function di(a,e){switch(a.type){case"string":return a.enum?.map(n=>JSON.stringify(n)).join(" | ")??"string";case"integer":case"number":return a.enum?.map(n=>`${n}`).join(" | ")??"number";case"boolean":return"boolean";case"null":return"null";case"array":return a.items?`${di(a.items,e)}[]`:"any[]";case"object":return`{
8
+ ${At(a,e+2,di)}
9
+ ${" ".repeat(e)}}`;default:return"any"}}function bs(a){let e=["namespace functions {",""];for(let n of a){n.description&&e.push(`// ${n.description}`);let{parameters:i}=n,r=i?.properties;if(!i||!r||Object.keys(r).length===0)e.push(`type ${n.name} = () => any;`);else{e.push(`type ${n.name} = (_: {`);let t=At(i,0,di);t.length>0&&e.push(t),e.push("}) => any;")}e.push("")}return e.push("} // namespace functions"),e.join(`
10
+ `)}function ks(a,e){let n=e(bs(a));return n+=9,n}function ys(a,e,n){return!e||n||a.role!=="system"||!a.content||a.content.endsWith(`
7
11
  `)?a:{...a,content:`${a.content}
8
- `}}function at(a,e){let{messages:n,functions:i,function_call:r}=a,t=!!(i&&i.length>0),s=!1,o=0;for(let l of n){let c=qr(l,t,s);(c!==l&&l.role==="system"||l.role==="system"&&t&&!s)&&(s=!0),o+=Br(c,e)}return o+=3,t&&i&&(o+=Gr(i,e),n.some(l=>l.role==="system")&&(o-=4)),r&&r!=="auto"&&(r==="none"?o+=1:typeof r=="object"&&r.name&&(o+=e(r.name)+4)),o}var nt=["chat-latest","chatgpt-4o-latest","codex-mini-latest","computer-use-preview","computer-use-preview-2025-03-11","daybreak-blue-latest","daybreak-red-latest","gpt-3.5","gpt-3.5-0301","gpt-3.5-turbo","gpt-3.5-turbo-0125","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-16k-0613","gpt-3.5-turbo-instruct","gpt-4","gpt-4-0125-preview","gpt-4-0314","gpt-4-0613","gpt-4-1106-preview","gpt-4-1106-vision-preview","gpt-4-32k","gpt-4-turbo","gpt-4-turbo-2024-04-09","gpt-4-turbo-preview","gpt-4.1","gpt-4.1-2025-04-14","gpt-4.1-mini","gpt-4.1-mini-2025-04-14","gpt-4.1-nano","gpt-4.1-nano-2025-04-14","gpt-4.5-preview","gpt-4.5-preview-2025-02-27","gpt-4o","gpt-4o-2024-05-13","gpt-4o-2024-08-06","gpt-4o-2024-11-20","gpt-4o-audio-preview","gpt-4o-audio-preview-2024-10-01","gpt-4o-audio-preview-2024-12-17","gpt-4o-audio-preview-2025-06-03","gpt-4o-mini","gpt-4o-mini-2024-07-18","gpt-4o-mini-audio-preview","gpt-4o-mini-audio-preview-2024-12-17","gpt-4o-mini-search-preview","gpt-4o-mini-search-preview-2025-03-11","gpt-4o-search-preview","gpt-4o-search-preview-2025-03-11","gpt-5","gpt-5-2025-08-07","gpt-5-chat-latest","gpt-5-codex","gpt-5-mini","gpt-5-mini-2025-08-07","gpt-5-nano","gpt-5-nano-2025-08-07","gpt-5-pro","gpt-5-pro-2025-10-06","gpt-5.1","gpt-5.1-2025-11-13","gpt-5.1-chat-latest","gpt-5.1-codex","gpt-5.1-codex-max","gpt-5.1-codex-mini","gpt-5.2","gpt-5.2-2025-12-11","gpt-5.2-chat-latest","gpt-5.2-codex","gpt-5.2-pro","gpt-5.2-pro-2025-12-11","gpt-5.3-chat-latest","gpt-5.3-codex","gpt-5.4","gpt-5.4-2026-03-05","gpt-5.4-mini","gpt-5.4-mini-2026-03-17","gpt-5.4-nano","gpt-5.4-nano-2026-03-17","gpt-5.4-pro","gpt-5.4-pro-2026-03-05","gpt-5.5","gpt-5.5-2026-04-23","gpt-5.5-pro","gpt-5.5-pro-2026-04-23","gpt-5.6-cyber","gpt-5.6-luna","gpt-5.6-sol","gpt-5.6-terra","gpt-audio","gpt-audio-1.5","gpt-audio-2025-08-28","gpt-audio-mini","gpt-audio-mini-2025-10-06","gpt-audio-mini-2025-12-15","gpt-image-1","gpt-oss-120b","gpt-oss-20b","o1","o1-2024-12-17","o1-mini","o1-mini-2024-09-12","o1-preview","o1-preview-2024-09-12","o1-pro","o1-pro-2025-03-19","o3","o3-2025-04-16","o3-deep-research","o3-deep-research-2025-06-26","o3-mini","o3-mini-2025-01-31","o3-pro","o3-pro-2025-06-10","o4-mini","o4-mini-2025-04-16","o4-mini-deep-research","o4-mini-deep-research-2025-06-26"];var it=Object.defineProperty,tt=(a,e)=>{let n={};for(var i in a)it(n,i,{get:a[i],enumerable:!0});return e||it(n,Symbol.toStringTag,{value:"Module"}),n};var rt=tt({cl100k_base:()=>Kr,gpt2:()=>Ur,o200k_base:()=>$r,o200k_harmony:()=>Jr,p50k_base:()=>Hr,p50k_edit:()=>Wr,r50k_base:()=>Vr}),Ur=["gpt2","gpt-2"],Hr=["text-davinci-002","text-davinci-003","code-davinci-001","code-davinci-002","davinci-codex","code-cushman-001","code-cushman-002","cushman-codex"],Vr=["text-ada-001","text-babbage-001","text-curie-001","text-davinci-001","ada","babbage","curie","davinci","code-search-ada-code-001","code-search-ada-text-001","text-similarity-ada-001","text-search-ada-doc-001","text-search-ada-query-001","text-similarity-babbage-001","text-search-babbage-doc-001","text-search-babbage-query-001","code-search-babbage-code-001","code-search-babbage-text-001","text-similarity-curie-001","text-search-curie-doc-001","text-search-curie-query-001","text-similarity-davinci-001","text-search-davinci-doc-001","text-search-davinci-query-001"],Wr=["code-davinci-edit-001","text-davinci-edit-001"],Kr=["gpt-3.5","gpt-3.5-0301","gpt-3.5-turbo","gpt-3.5-turbo-0125","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-16k-0613","gpt-3.5-turbo-instruct","gpt-4","gpt-4-0125-preview","gpt-4-0314","gpt-4-0613","gpt-4-1106-preview","gpt-4-1106-vision-preview","gpt-4-32k","gpt-4-turbo","gpt-4-turbo-2024-04-09","gpt-4-turbo-preview","text-embedding-3-large","text-embedding-3-small","text-embedding-ada-002","babbage-002","davinci-002"],$r=[],Jr=["gpt-oss-20b","gpt-oss-120b"];var st=Object.fromEntries(Object.entries(rt).flatMap(([a,e])=>e.map(n=>[n,a]))),Yr={messageSeparator:`
12
+ `}}function Tt(a,e){let{messages:n,functions:i,function_call:r}=a,t=!!(i&&i.length>0),s=!1,o=0;for(let l of n){let c=ys(l,t,s);(c!==l&&l.role==="system"||l.role==="system"&&t&&!s)&&(s=!0),o+=fs(c,e)}return o+=3,t&&i&&(o+=ks(i,e),n.some(l=>l.role==="system")&&(o-=4)),r&&r!=="auto"&&(r==="none"?o+=1:typeof r=="object"&&r.name&&(o+=e(r.name)+4)),o}var Ct=["chat-latest","chatgpt-4o-latest","codex-mini-latest","computer-use-preview","computer-use-preview-2025-03-11","daybreak-blue-latest","daybreak-red-latest","gpt-3.5","gpt-3.5-0301","gpt-3.5-turbo","gpt-3.5-turbo-0125","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-16k-0613","gpt-3.5-turbo-instruct","gpt-4","gpt-4-0125-preview","gpt-4-0314","gpt-4-0613","gpt-4-1106-preview","gpt-4-1106-vision-preview","gpt-4-32k","gpt-4-turbo","gpt-4-turbo-2024-04-09","gpt-4-turbo-preview","gpt-4.1","gpt-4.1-2025-04-14","gpt-4.1-mini","gpt-4.1-mini-2025-04-14","gpt-4.1-nano","gpt-4.1-nano-2025-04-14","gpt-4.5-preview","gpt-4.5-preview-2025-02-27","gpt-4o","gpt-4o-2024-05-13","gpt-4o-2024-08-06","gpt-4o-2024-11-20","gpt-4o-audio-preview","gpt-4o-audio-preview-2024-10-01","gpt-4o-audio-preview-2024-12-17","gpt-4o-audio-preview-2025-06-03","gpt-4o-mini","gpt-4o-mini-2024-07-18","gpt-4o-mini-audio-preview","gpt-4o-mini-audio-preview-2024-12-17","gpt-4o-mini-search-preview","gpt-4o-mini-search-preview-2025-03-11","gpt-4o-search-preview","gpt-4o-search-preview-2025-03-11","gpt-5","gpt-5-2025-08-07","gpt-5-chat-latest","gpt-5-codex","gpt-5-mini","gpt-5-mini-2025-08-07","gpt-5-nano","gpt-5-nano-2025-08-07","gpt-5-pro","gpt-5-pro-2025-10-06","gpt-5.1","gpt-5.1-2025-11-13","gpt-5.1-chat-latest","gpt-5.1-codex","gpt-5.1-codex-max","gpt-5.1-codex-mini","gpt-5.2","gpt-5.2-2025-12-11","gpt-5.2-chat-latest","gpt-5.2-codex","gpt-5.2-pro","gpt-5.2-pro-2025-12-11","gpt-5.3-chat-latest","gpt-5.3-codex","gpt-5.4","gpt-5.4-2026-03-05","gpt-5.4-mini","gpt-5.4-mini-2026-03-17","gpt-5.4-nano","gpt-5.4-nano-2026-03-17","gpt-5.4-pro","gpt-5.4-pro-2026-03-05","gpt-5.5","gpt-5.5-2026-04-23","gpt-5.5-pro","gpt-5.5-pro-2026-04-23","gpt-5.6-cyber","gpt-5.6-luna","gpt-5.6-sol","gpt-5.6-terra","gpt-audio","gpt-audio-1.5","gpt-audio-2025-08-28","gpt-audio-mini","gpt-audio-mini-2025-10-06","gpt-audio-mini-2025-12-15","gpt-image-1","gpt-oss-120b","gpt-oss-20b","o1","o1-2024-12-17","o1-mini","o1-mini-2024-09-12","o1-preview","o1-preview-2024-09-12","o1-pro","o1-pro-2025-03-19","o3","o3-2025-04-16","o3-deep-research","o3-deep-research-2025-06-26","o3-mini","o3-mini-2025-01-31","o3-pro","o3-pro-2025-06-10","o4-mini","o4-mini-2025-04-16","o4-mini-deep-research","o4-mini-deep-research-2025-06-26"];var Rt=Object.defineProperty,Pt=(a,e)=>{let n={};for(var i in a)Rt(n,i,{get:a[i],enumerable:!0});return e||Rt(n,Symbol.toStringTag,{value:"Module"}),n};var zt=Pt({cl100k_base:()=>Es,gpt2:()=>vs,o200k_base:()=>As,o200k_harmony:()=>Ts,p50k_base:()=>ws,p50k_edit:()=>_s,r50k_base:()=>Ss}),vs=["gpt2","gpt-2"],ws=["text-davinci-002","text-davinci-003","code-davinci-001","code-davinci-002","davinci-codex","code-cushman-001","code-cushman-002","cushman-codex"],Ss=["text-ada-001","text-babbage-001","text-curie-001","text-davinci-001","ada","babbage","curie","davinci","code-search-ada-code-001","code-search-ada-text-001","text-similarity-ada-001","text-search-ada-doc-001","text-search-ada-query-001","text-similarity-babbage-001","text-search-babbage-doc-001","text-search-babbage-query-001","code-search-babbage-code-001","code-search-babbage-text-001","text-similarity-curie-001","text-search-curie-doc-001","text-search-curie-query-001","text-similarity-davinci-001","text-search-davinci-doc-001","text-search-davinci-query-001"],_s=["code-davinci-edit-001","text-davinci-edit-001"],Es=["gpt-3.5","gpt-3.5-0301","gpt-3.5-turbo","gpt-3.5-turbo-0125","gpt-3.5-turbo-0613","gpt-3.5-turbo-1106","gpt-3.5-turbo-16k-0613","gpt-3.5-turbo-instruct","gpt-4","gpt-4-0125-preview","gpt-4-0314","gpt-4-0613","gpt-4-1106-preview","gpt-4-1106-vision-preview","gpt-4-32k","gpt-4-turbo","gpt-4-turbo-2024-04-09","gpt-4-turbo-preview","text-embedding-3-large","text-embedding-3-small","text-embedding-ada-002","babbage-002","davinci-002"],As=[],Ts=["gpt-oss-20b","gpt-oss-120b"];var It=Object.fromEntries(Object.entries(zt).flatMap(([a,e])=>e.map(n=>[n,a]))),Cs={messageSeparator:`
9
13
  `,roleSeparator:`
10
- `},Xr={messageSeparator:"",roleSeparator:Le},ot=Object.fromEntries(nt.flatMap(a=>a.startsWith("gpt-3.5")?[[a,Yr]]:[[a,Xr]]));var ka=new RegExp("'s|'t|'re|'ve|'m|'ll|'d| ?\\p{L}+| ?\\p{N}+| ?[^\\s\\p{L}\\p{N}]+|\\s+(?!\\S)|\\s+","gu"),ct=String.raw`'(?:[sS]|[dD]|[mM]|[tT]|[lL][lL]|[vV][eE]|[rR][eE])`,lt=String.raw`(?:${ct})?`,Qr=String.raw`${ct}|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s+$|\s*[\r\n]|\s+(?!\S)|\s`,ut=new RegExp(Qr,"gu"),Zr=String.raw`[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]*[\p{Ll}\p{Lm}\p{Lo}\p{M}]+${lt}|[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]+[\p{Ll}\p{Lm}\p{Lo}\p{M}]*${lt}|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n/]*|\s*[\r\n]+|\s+(?!\S)|\s+`,tn=new RegExp(Zr,"gu");function dt(a){return{tokenSplitRegex:ut,bytePairRankDecoder:a,specialTokensEncoder:new Map([[le,100257],[Oe,100258],[De,100259],[Ne,100260],[ia,100264],[ta,100265],[Le,100266],[Be,100276]])}}var es=[[le,199999],[Oe,2e5],[De,200001],[Ne,200002],[ia,200003],[ta,200004],[Le,200005],[Be,200006]],as=()=>new Map(es);function mt(a){return{tokenSplitRegex:tn,bytePairRankDecoder:a,specialTokensEncoder:as()}}var ns=200013,is=201088,ts=[[Hn,199998],[le,199999],["<|reserved_200000|>",2e5],["<|reserved_200001|>",200001],[Ma,200002],[ja,200003],["<|reserved_200004|>",200004],[xa,200005],[Pa,200006],[za,200007],[Ia,200008],["<|reserved_200009|>",200009],["<|reserved_200010|>",200010],["<|reserved_200011|>",200011],[Oa,200012]];function pt(a){let e=new Map(ts);for(let n=ns;n<is;n+=1)e.set(`<|reserved_${n}|>`,n);return e.set(Be,200018),{tokenSplitRegex:tn,bytePairRankDecoder:a,specialTokensEncoder:e,chatFormatter:"harmony"}}function gt(a){return{expectedVocabularySize:50281,tokenSplitRegex:ka,bytePairRankDecoder:a,specialTokensEncoder:new Map([[le,50256]])}}function ht(a){return{tokenSplitRegex:ka,bytePairRankDecoder:a,specialTokensEncoder:new Map([[le,50256],[Oe,50281],[De,50282],[Ne,50283]])}}function bt(a){return{expectedVocabularySize:50257,tokenSplitRegex:ka,bytePairRankDecoder:a,specialTokensEncoder:new Map([[le,50256]])}}function Jn(a,e){let n=e(a);switch(a.toLowerCase()){case"gpt2":case"r50k_base":return bt(n);case"p50k_base":return gt(n);case"p50k_edit":return ht(n);case"cl100k_base":return dt(n);case"o200k_base":return mt(n);case"o200k_harmony":return pt(n);default:throw new Error(`Unknown encoding name: ${a}`)}}var ft=class Yn{static EndOfPrompt=Be;static EndOfText=le;static FimMiddle=De;static FimPrefix=Oe;static FimSuffix=Ne;modelName;modelSpec;bytePairEncodingCoreProcessor;specialTokensEncoder;specialTokensSet;allSpecialTokenRegex;defaultSpecialTokenConfig;chatFormatter;countChatCompletionTokens;vocabularySize;constructor({bytePairRankDecoder:e,specialTokensEncoder:n,expectedVocabularySize:i,modelName:r,modelSpec:t,chatFormatter:s,...o}){this.specialTokensEncoder=n,this.specialTokensSet=new Set(this.specialTokensEncoder.keys()),this.allSpecialTokenRegex=Kn(this.specialTokensSet),this.bytePairEncodingCoreProcessor=new Zi({bytePairRankDecoder:e,specialTokensEncoder:n,...o}),this.defaultSpecialTokenConfig=this.processSpecialTokens();let l=Math.max(e.length-1,Xi(n));if(this.vocabularySize=this.bytePairEncodingCoreProcessor.mergeableBytePairRankCount+n.size,i!==void 0){if(this.vocabularySize!==i)throw new Error("The number of mergeable tokens and special tokens must be equal to expectedVocabularySize.");if(l!==i-1)throw new Error(`The model encodings are invalid. The maximum token value must be equal to expectedVocabularySize - 1. Currently ${l}, expected ${i-1}`)}this.encode=this.encode.bind(this),this.decode=this.decode.bind(this),this.encodeGenerator=this.encodeGenerator.bind(this),this.decodeGenerator=this.decodeGenerator.bind(this),this.decodeAsyncGenerator=this.decodeAsyncGenerator.bind(this),this.decodeAsync=this.decodeAsync.bind(this),this.isWithinTokenLimit=this.isWithinTokenLimit.bind(this),this.encodeChat=this.encodeChat.bind(this),this.encodeChatGenerator=this.encodeChatGenerator.bind(this),this.countTokens=this.countTokens.bind(this),this.setMergeCacheSize=this.setMergeCacheSize.bind(this),this.clearMergeCache=this.clearMergeCache.bind(this),this.estimateCost=this.estimateCost.bind(this),t?.supported_features?.includes("function_calling")&&(this.countChatCompletionTokens=this.countChatCompletionTokensInternal.bind(this)),this.modelName=r,this.modelSpec=t,this.chatFormatter=s??"chatml"}*encodeHarmonyChatGenerator(e,n){let i=this.specialTokensEncoder.get(Pa),r=this.specialTokensEncoder.get(Ia),t=this.specialTokensEncoder.get(za),s=this.specialTokensEncoder.get(Ma),o=this.specialTokensEncoder.get(Oa),l=this.specialTokensEncoder.get(xa),c=this.specialTokensEncoder.get(ja);if(i===void 0||r===void 0||t===void 0||s===void 0||o===void 0||l===void 0||c===void 0)throw new Error("Harmony chat format requires dedicated special tokens.");let u=E=>E.length>0?this.encode(E):[],g=E=>{switch(E){case"<|return|>":return s;case"<|call|>":return o;default:return t}};for(let E of e){if(E.content===void 0)throw new Error("Content must be defined for all messages.");let I=E.name??E.role??"user";yield[i],yield u(I);let S=E.recipient&&(E.recipientPlacement==="role"||!E.channel),N=E.recipient&&!S;S&&(yield u(` to=${E.recipient}`)),E.channel&&(yield[l],yield u(E.channel),N&&(yield u(` to=${E.recipient}`))),E.constraint&&(yield[c],yield u(E.constraint)),yield[r],yield*this.encodeGenerator(E.content,n),yield[g(E.terminator)]}let h=n?.primeWithAssistantResponse??"assistant";h.length>0&&(yield[i],yield u(h))}static getEncodingApi(e,n){let i=Jn(e,n);return new Yn(i)}static getEncodingApiForModel(e,n,i){let r=st[e]??"o200k_base",t=Jn(r,n);return new Yn({...t,modelName:e,modelSpec:i})}processSpecialTokens({allowedSpecial:e,disallowedSpecial:n}={}){let i;if(e==="all"||e?.has("all")){e=new Set(this.specialTokensSet);let r=e;if(n==="all")throw new Error('allowedSpecial and disallowedSpecial cannot both be set to "all".');typeof n=="object"?n.forEach(t=>r.delete(t)):n=new Set}if(!n||n==="all"||n.has("all")){n=new Set(this.specialTokensSet);let r=n;e?.size?(e.forEach(t=>r.delete(t)),n.forEach(t=>e.delete(t)),n.size>0&&(i=Kn(n))):i=this.allSpecialTokenRegex}return{allowedSpecial:e,regexPattern:i}}encodeGenerator(e,n){let i=n?this.processSpecialTokens(n):this.defaultSpecialTokenConfig;if(i.regexPattern){let r=e.match(i.regexPattern);if(r!==null)throw new Error(`Disallowed special token found: ${r[0]}`)}return this.bytePairEncodingCoreProcessor.encodeNativeGenerator(e,i.allowedSpecial)}encode(e,n){let i=n?this.processSpecialTokens(n):this.defaultSpecialTokenConfig;if(i.regexPattern){let r=e.match(i.regexPattern);if(r!==null)throw new Error(`Disallowed special token found: ${r[0]}`)}return this.bytePairEncodingCoreProcessor.encodeNative(e,i.allowedSpecial)}*encodeChatGenerator(e,n=this.modelName,i){if(!n)throw new Error("Model name must be provided either during initialization or passed in to the method.");let r=ot[n];if(!r)throw new Error(`Model '${n}' does not support chat.`);if(this.chatFormatter==="harmony"){yield*this.encodeHarmonyChatGenerator(e,i);return}let t=this.specialTokensEncoder.get(ia),s=this.specialTokensEncoder.get(ta);if(t===void 0||s===void 0)throw new Error(`Model '${n}' does not support chat.`);let o=new Set([Le]),{messageSeparator:l,roleSeparator:c}=r,u=l.length>0?this.encode(l):[],g=c.length>0?this.encode(c,{allowedSpecial:o}):[],h=new Map;for(let{role:I="system",name:S=I,content:N}of e){if(N===void 0)throw new Error("Content must be defined for all messages.");yield[t];let V=h.get(S)??this.encode(S);h.set(S,V),yield V,g.length>0&&(yield g),yield*this.encodeGenerator(N,i),yield[s],yield u}let E=i?.primeWithAssistantResponse??"assistant";E.length>0&&(yield[t],yield*this.encodeGenerator(E,i)),g.length>0&&(yield g)}encodeChat(e,n=this.modelName,i){return[...this.encodeChatGenerator(e,n,i)].flat()}isWithinTokenLimit(e,n,i){let r=typeof e=="string"?this.encodeGenerator(e,i):this.encodeChatGenerator(e,void 0,i),t=0;for(let s of r)if(t+=s.length,t>n)return!1;return t}countTokens(e,n){if(typeof e=="string"){let t=n?this.processSpecialTokens(n):this.defaultSpecialTokenConfig;if(t.regexPattern){let s=e.match(t.regexPattern);if(s!==null)throw new Error(`Disallowed special token found: ${s[0]}`)}return this.bytePairEncodingCoreProcessor.countNative(e,t.allowedSpecial)}let i=this.encodeChatGenerator(e,void 0,n),r=0;for(let t of i)r+=t.length;return r}countStringTokens(e){return e?this.bytePairEncodingCoreProcessor.countNative(e):0}countChatCompletionTokensInternal(e){return at(e,n=>this.countStringTokens(n))}setMergeCacheSize(e){this.bytePairEncodingCoreProcessor.setMergeCacheSize(e)}clearMergeCache(){this.bytePairEncodingCoreProcessor.clearMergeCache()}decode(e){return this.bytePairEncodingCoreProcessor.decodeNative(e)}*decodeGenerator(e){let n=this.bytePairEncodingCoreProcessor.decodeNativeGenerator(e),i="";for(let r of n)i+=typeof r=="string"?r:fa.decode(r,{stream:!0}),!(i.length===0||Vn(i))&&(yield i,i="");i.length>0&&(yield i)}async*decodeAsyncGenerator(e){let n=this.bytePairEncodingCoreProcessor.decodeNativeAsyncIterable(e),i="";for await(let r of n)i+=typeof r=="string"?r:fa.decode(r,{stream:!0}),!(i.length===0||Vn(i))&&(yield i,i="");i.length>0&&(yield i)}async decodeAsync(e){let n=this.bytePairEncodingCoreProcessor.decodeNativeAsyncIterable(e),i="";for await(let r of n)i+=typeof r=="string"?r:fa.decode(r,{stream:!0});return i}estimateCost(e,n=this.modelSpec){if(!n)throw new Error("Model spec must be provided either during initialization or passed in to the method.");if(!n.price_data)throw new Error(`No cost information available for model: ${n.name}`);let i=n.price_data,r={},t=e/1e6;return i.main&&(r.main={input:i.main.input&&i.main.input*t,output:i.main.output&&i.main.output*t,cached_input:i.main.cached_input&&i.main.cached_input*t,cached_output:i.main.cached_output&&i.main.cached_output*t}),i.batch&&(r.batch={input:i.batch.input&&i.batch.input*t,output:i.batch.output&&i.batch.output*t,cached_input:i.batch.cached_input&&i.batch.cached_input*t,cached_output:i.batch.cached_output&&i.batch.cached_output*t}),r}};var kt=["!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~",[161],[162],[163],[164],[165],[166],[167],[168],[169],[170],[171],[172],[174],[175],[176],[177],[178],[179],[180],[181],[182],[183],[184],[185],[186],[187],[188],[189],[190],[191],[192],[193],[194],[195],[196],[197],[198],[199],[200],[201],[202],[203],[204],[205],[206],[207],[208],[209],[210],[211],[212],[213],[214],[215],[216],[217],[218],[219],[220],[221],[222],[223],[224],[225],[226],[227],[228],[229],[230],[231],[232],[233],[234],[235],[236],[237],[238],[239],[240],[241],[242],[243],[244],[245],[246],[247],[248],[249],[250],[251],[252],[253],[254],[255],"\0","","","","","","","\x07","\b"," ",`
14
+ `},Rs={messageSeparator:"",roleSeparator:qe},xt=Object.fromEntries(Ct.flatMap(a=>a.startsWith("gpt-3.5")?[[a,Cs]]:[[a,Rs]]));var Ta=new RegExp("'s|'t|'re|'ve|'m|'ll|'d| ?\\p{L}+| ?\\p{N}+| ?[^\\s\\p{L}\\p{N}]+|\\s+(?!\\S)|\\s+","gu"),jt=String.raw`'(?:[sS]|[dD]|[mM]|[tT]|[lL][lL]|[vV][eE]|[rR][eE])`,Mt=String.raw`(?:${jt})?`,Ps=String.raw`${jt}|[^\r\n\p{L}\p{N}]?\p{L}+|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n]*|\s+$|\s*[\r\n]|\s+(?!\S)|\s`,Ot=new RegExp(Ps,"gu"),zs=String.raw`[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]*[\p{Ll}\p{Lm}\p{Lo}\p{M}]+${Mt}|[^\r\n\p{L}\p{N}]?[\p{Lu}\p{Lt}\p{Lm}\p{Lo}\p{M}]+[\p{Ll}\p{Lm}\p{Lo}\p{M}]*${Mt}|\p{N}{1,3}| ?[^\s\p{L}\p{N}]+[\r\n/]*|\s*[\r\n]+|\s+(?!\S)|\s+`,vn=new RegExp(zs,"gu");function Dt(a){return{tokenSplitRegex:Ot,bytePairRankDecoder:a,specialTokensEncoder:new Map([[de,100257],[Be,100258],[Fe,100259],[Ge,100260],[da,100264],[ma,100265],[qe,100266],[Ue,100276]])}}var Is=[[de,199999],[Be,2e5],[Fe,200001],[Ge,200002],[da,200003],[ma,200004],[qe,200005],[Ue,200006]],xs=()=>new Map(Is);function Nt(a){return{tokenSplitRegex:vn,bytePairRankDecoder:a,specialTokensEncoder:xs()}}var Ms=200013,js=201088,Os=[[oi,199998],[de,199999],["<|reserved_200000|>",2e5],["<|reserved_200001|>",200001],[qa,200002],[Ua,200003],["<|reserved_200004|>",200004],[Ga,200005],[La,200006],[Ba,200007],[Fa,200008],["<|reserved_200009|>",200009],["<|reserved_200010|>",200010],["<|reserved_200011|>",200011],[Ha,200012]];function Lt(a){let e=new Map(Os);for(let n=Ms;n<js;n+=1)e.set(`<|reserved_${n}|>`,n);return e.set(Ue,200018),{tokenSplitRegex:vn,bytePairRankDecoder:a,specialTokensEncoder:e,chatFormatter:"harmony"}}function Bt(a){return{expectedVocabularySize:50281,tokenSplitRegex:Ta,bytePairRankDecoder:a,specialTokensEncoder:new Map([[de,50256]])}}function Ft(a){return{tokenSplitRegex:Ta,bytePairRankDecoder:a,specialTokensEncoder:new Map([[de,50256],[Be,50281],[Fe,50282],[Ge,50283]])}}function Gt(a){return{expectedVocabularySize:50257,tokenSplitRegex:Ta,bytePairRankDecoder:a,specialTokensEncoder:new Map([[de,50256]])}}function mi(a,e){let n=e(a);switch(a.toLowerCase()){case"gpt2":case"r50k_base":return Gt(n);case"p50k_base":return Bt(n);case"p50k_edit":return Ft(n);case"cl100k_base":return Dt(n);case"o200k_base":return Nt(n);case"o200k_harmony":return Lt(n);default:throw new Error(`Unknown encoding name: ${a}`)}}var qt=class pi{static EndOfPrompt=Ue;static EndOfText=de;static FimMiddle=Fe;static FimPrefix=Be;static FimSuffix=Ge;modelName;modelSpec;bytePairEncodingCoreProcessor;specialTokensEncoder;specialTokensSet;allSpecialTokenRegex;defaultSpecialTokenConfig;chatFormatter;countChatCompletionTokens;vocabularySize;constructor({bytePairRankDecoder:e,specialTokensEncoder:n,expectedVocabularySize:i,modelName:r,modelSpec:t,chatFormatter:s,...o}){this.specialTokensEncoder=n,this.specialTokensSet=new Set(this.specialTokensEncoder.keys()),this.allSpecialTokenRegex=ui(this.specialTokensSet),this.bytePairEncodingCoreProcessor=new Et({bytePairRankDecoder:e,specialTokensEncoder:n,...o}),this.defaultSpecialTokenConfig=this.processSpecialTokens();let l=Math.max(e.length-1,St(n));if(this.vocabularySize=this.bytePairEncodingCoreProcessor.mergeableBytePairRankCount+n.size,i!==void 0){if(this.vocabularySize!==i)throw new Error("The number of mergeable tokens and special tokens must be equal to expectedVocabularySize.");if(l!==i-1)throw new Error(`The model encodings are invalid. The maximum token value must be equal to expectedVocabularySize - 1. Currently ${l}, expected ${i-1}`)}this.encode=this.encode.bind(this),this.decode=this.decode.bind(this),this.encodeGenerator=this.encodeGenerator.bind(this),this.decodeGenerator=this.decodeGenerator.bind(this),this.decodeAsyncGenerator=this.decodeAsyncGenerator.bind(this),this.decodeAsync=this.decodeAsync.bind(this),this.isWithinTokenLimit=this.isWithinTokenLimit.bind(this),this.encodeChat=this.encodeChat.bind(this),this.encodeChatGenerator=this.encodeChatGenerator.bind(this),this.countTokens=this.countTokens.bind(this),this.setMergeCacheSize=this.setMergeCacheSize.bind(this),this.clearMergeCache=this.clearMergeCache.bind(this),this.estimateCost=this.estimateCost.bind(this),t?.supported_features?.includes("function_calling")&&(this.countChatCompletionTokens=this.countChatCompletionTokensInternal.bind(this)),this.modelName=r,this.modelSpec=t,this.chatFormatter=s??"chatml"}*encodeHarmonyChatGenerator(e,n){let i=this.specialTokensEncoder.get(La),r=this.specialTokensEncoder.get(Fa),t=this.specialTokensEncoder.get(Ba),s=this.specialTokensEncoder.get(qa),o=this.specialTokensEncoder.get(Ha),l=this.specialTokensEncoder.get(Ga),c=this.specialTokensEncoder.get(Ua);if(i===void 0||r===void 0||t===void 0||s===void 0||o===void 0||l===void 0||c===void 0)throw new Error("Harmony chat format requires dedicated special tokens.");let u=y=>y.length>0?this.encode(y):[],g=y=>{switch(y){case"<|return|>":return s;case"<|call|>":return o;default:return t}};for(let y of e){if(y.content===void 0)throw new Error("Content must be defined for all messages.");let I=y.name??y.role??"user";yield[i],yield u(I);let E=y.recipient&&(y.recipientPlacement==="role"||!y.channel),H=y.recipient&&!E;E&&(yield u(` to=${y.recipient}`)),y.channel&&(yield[l],yield u(y.channel),H&&(yield u(` to=${y.recipient}`))),y.constraint&&(yield[c],yield u(y.constraint)),yield[r],yield*this.encodeGenerator(y.content,n),yield[g(y.terminator)]}let h=n?.primeWithAssistantResponse??"assistant";h.length>0&&(yield[i],yield u(h))}static getEncodingApi(e,n){let i=mi(e,n);return new pi(i)}static getEncodingApiForModel(e,n,i){let r=It[e]??"o200k_base",t=mi(r,n);return new pi({...t,modelName:e,modelSpec:i})}processSpecialTokens({allowedSpecial:e,disallowedSpecial:n}={}){let i;if(e==="all"||e?.has("all")){e=new Set(this.specialTokensSet);let r=e;if(n==="all")throw new Error('allowedSpecial and disallowedSpecial cannot both be set to "all".');typeof n=="object"?n.forEach(t=>r.delete(t)):n=new Set}if(!n||n==="all"||n.has("all")){n=new Set(this.specialTokensSet);let r=n;e?.size?(e.forEach(t=>r.delete(t)),n.forEach(t=>e.delete(t)),n.size>0&&(i=ui(n))):i=this.allSpecialTokenRegex}return{allowedSpecial:e,regexPattern:i}}encodeGenerator(e,n){let i=n?this.processSpecialTokens(n):this.defaultSpecialTokenConfig;if(i.regexPattern){let r=e.match(i.regexPattern);if(r!==null)throw new Error(`Disallowed special token found: ${r[0]}`)}return this.bytePairEncodingCoreProcessor.encodeNativeGenerator(e,i.allowedSpecial)}encode(e,n){let i=n?this.processSpecialTokens(n):this.defaultSpecialTokenConfig;if(i.regexPattern){let r=e.match(i.regexPattern);if(r!==null)throw new Error(`Disallowed special token found: ${r[0]}`)}return this.bytePairEncodingCoreProcessor.encodeNative(e,i.allowedSpecial)}*encodeChatGenerator(e,n=this.modelName,i){if(!n)throw new Error("Model name must be provided either during initialization or passed in to the method.");let r=xt[n];if(!r)throw new Error(`Model '${n}' does not support chat.`);if(this.chatFormatter==="harmony"){yield*this.encodeHarmonyChatGenerator(e,i);return}let t=this.specialTokensEncoder.get(da),s=this.specialTokensEncoder.get(ma);if(t===void 0||s===void 0)throw new Error(`Model '${n}' does not support chat.`);let o=new Set([qe]),{messageSeparator:l,roleSeparator:c}=r,u=l.length>0?this.encode(l):[],g=c.length>0?this.encode(c,{allowedSpecial:o}):[],h=new Map;for(let{role:I="system",name:E=I,content:H}of e){if(H===void 0)throw new Error("Content must be defined for all messages.");yield[t];let W=h.get(E)??this.encode(E);h.set(E,W),yield W,g.length>0&&(yield g),yield*this.encodeGenerator(H,i),yield[s],yield u}let y=i?.primeWithAssistantResponse??"assistant";y.length>0&&(yield[t],yield*this.encodeGenerator(y,i)),g.length>0&&(yield g)}encodeChat(e,n=this.modelName,i){return[...this.encodeChatGenerator(e,n,i)].flat()}isWithinTokenLimit(e,n,i){let r=typeof e=="string"?this.encodeGenerator(e,i):this.encodeChatGenerator(e,void 0,i),t=0;for(let s of r)if(t+=s.length,t>n)return!1;return t}countTokens(e,n){if(typeof e=="string"){let t=n?this.processSpecialTokens(n):this.defaultSpecialTokenConfig;if(t.regexPattern){let s=e.match(t.regexPattern);if(s!==null)throw new Error(`Disallowed special token found: ${s[0]}`)}return this.bytePairEncodingCoreProcessor.countNative(e,t.allowedSpecial)}let i=this.encodeChatGenerator(e,void 0,n),r=0;for(let t of i)r+=t.length;return r}countStringTokens(e){return e?this.bytePairEncodingCoreProcessor.countNative(e):0}countChatCompletionTokensInternal(e){return Tt(e,n=>this.countStringTokens(n))}setMergeCacheSize(e){this.bytePairEncodingCoreProcessor.setMergeCacheSize(e)}clearMergeCache(){this.bytePairEncodingCoreProcessor.clearMergeCache()}decode(e){return this.bytePairEncodingCoreProcessor.decodeNative(e)}*decodeGenerator(e){let n=this.bytePairEncodingCoreProcessor.decodeNativeGenerator(e),i="";for(let r of n)i+=typeof r=="string"?r:Aa.decode(r,{stream:!0}),!(i.length===0||li(i))&&(yield i,i="");i.length>0&&(yield i)}async*decodeAsyncGenerator(e){let n=this.bytePairEncodingCoreProcessor.decodeNativeAsyncIterable(e),i="";for await(let r of n)i+=typeof r=="string"?r:Aa.decode(r,{stream:!0}),!(i.length===0||li(i))&&(yield i,i="");i.length>0&&(yield i)}async decodeAsync(e){let n=this.bytePairEncodingCoreProcessor.decodeNativeAsyncIterable(e),i="";for await(let r of n)i+=typeof r=="string"?r:Aa.decode(r,{stream:!0});return i}estimateCost(e,n=this.modelSpec){if(!n)throw new Error("Model spec must be provided either during initialization or passed in to the method.");if(!n.price_data)throw new Error(`No cost information available for model: ${n.name}`);let i=n.price_data,r={},t=e/1e6;return i.main&&(r.main={input:i.main.input&&i.main.input*t,output:i.main.output&&i.main.output*t,cached_input:i.main.cached_input&&i.main.cached_input*t,cached_output:i.main.cached_output&&i.main.cached_output*t}),i.batch&&(r.batch={input:i.batch.input&&i.batch.input*t,output:i.batch.output&&i.batch.output*t,cached_input:i.batch.cached_input&&i.batch.cached_input*t,cached_output:i.batch.cached_output&&i.batch.cached_output*t}),r}};var Ut=["!",'"',"#","$","%","&","'","(",")","*","+",",","-",".","/","0","1","2","3","4","5","6","7","8","9",":",";","<","=",">","?","@","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\\","]","^","_","`","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","{","|","}","~",[161],[162],[163],[164],[165],[166],[167],[168],[169],[170],[171],[172],[174],[175],[176],[177],[178],[179],[180],[181],[182],[183],[184],[185],[186],[187],[188],[189],[190],[191],[192],[193],[194],[195],[196],[197],[198],[199],[200],[201],[202],[203],[204],[205],[206],[207],[208],[209],[210],[211],[212],[213],[214],[215],[216],[217],[218],[219],[220],[221],[222],[223],[224],[225],[226],[227],[228],[229],[230],[231],[232],[233],[234],[235],[236],[237],[238],[239],[240],[241],[242],[243],[244],[245],[246],[247],[248],[249],[250],[251],[252],[253],[254],[255],"\0","","","","","","","\x07","\b"," ",`
11
15
  `,"\v","\f","\r","","","","","","","","","","","","","","\x1B","","","",""," ","\x7F",[128],[129],[130],[131],[132],[133],[134],[135],[136],[137],[138],[139],[140],[141],[142],[143],[144],[145],[146],[147],[148],[149],[150],[151],[152],[153],[154],[155],[156],[157],[158],[159],[160],[173]," "," ","in","er"," t"," a","en","on","re"," s","at","or","es"," ","an"," "," d","he"," c"," p","is","ar","it",`
12
16
 
13
17
  `,"al",[224,164],"le","ou"," m"," f"," w"," b","as","ing"," the","ic","et"," o","ion","ed","el"," n","ro","ent",[32,208],"nd","st",[225,131],"\u0430"," l"," in",`;
@@ -1808,7 +1812,7 @@ ${" ".repeat(e)}}`;default:return"any"}}function Fr(a){let e=["namespace functio
1808
1812
 
1809
1813
  `," d\xE9pass","\u0192","\u05E4\u05E7\u05D9\u05D3","nera","\u0E40\u0E21\u0E37\u0E2D\u0E07"," vaya"," particulars"," moreover"," gato"," aner"," Hale","Floating","\u0435\u049B\u0438\u043D",".Math","annual","_gain",".Infrastructure",".ignore"," waits","wk"," dispro","Tin"," anima","\u5B8B","\u0630\u0641"," \u0434\u0435\u0441\u044F\u0442"," moderation","\u622A\u56FE","-match"," promoci\xF3n"," vergeten"," Providence","swiper",'"\u05D9',"amua","winner","BUILD","\u5177\u6709",">';"," bilden"," \u0915\u0941\u0928\u0948"," Sellers","Innen","okin","trat"," sega","-\u0576",".Contact"," equipments","IPA","\u09C7\u09B6\u09A8",">Name","(EXIT"," durchgef\xFChrt"," \u5927\u53D1\u5FEB\u4E09\u5F00\u5956","_adapter"," aaye","\u0CAC\u0CB9\u0CC1\u0CA6\u0CC1","izzato"," demolition"," adem"," \u0C1A\u0C46\u0C02\u0C26\u0C3F\u0C28"," shines"," SECTION"," pade"," lifespan"," \u8FDE"," Hes"," Roles","ASCADE","ngo"," moni","Expansion","Ranking"," \u0BB5\u0B95","veyor"," Sharma"," \u0442\u0438\u0433","(Chat"," SCORE"," pointe"," \u092E\u0928\u094D\u0924"," \u0627\u0644\u062F\u0643\u062A\u0648\u0631"," \u10E2\u10D4\u10E0","\u0C30\u0C4D\u0C1A"," \u043B\u044E\u0431\u043E\u043C"," \u0432\u043E\u0441\u043F\u0430\u043B"," \u0939\u092E\u093E\u0930\u0940"," alimento"," hant"," minist\xE8re"," Ney"," \u0432\u043E\u0437\u0434\u0443\u0445"," Benedict"," advises"," informazioni"," garant\xEDa",":C","kert","etcode","(Enum","\u0440\u0430\u043B\u0430",".DATA","\uFF3F\u8001\u53F8\u673A"," \u0442\u0435\u0430\u0442"," proportional"," \u0A97\u0AAF\u0ACB"," Admir","\u0440\u044F"," t\xF6\xF6t"," \u044F\u043A\u0430\u044F"," \xC9l","st\xE4nde"," dyr","imbali"," siunners","\u09E7\u09E8"," \xE1ra"," \u0645\u0645\u062A","Expiry","addir"," neatly"," \u0411\u0443\u0434"," \u25BA","\u0E32\u0E2B\u0E32\u0E23"," hawa"," liitty"," \u043A\u0430\u043F\u0438\u0442"," aisle","_character"," Yen","\u5341\u5206"," \u0D09\u0D2F","(hr"," ukuth"," Gecko"," considerada"," Seasons","quettes"," certificado","utterstock"," \u0AA4\u0ABE\u0AB2","asarkan","\u0E27\u0E21"," \u0447\u0435\u0442\u0432\u0435\u0440"," \u05E9\u05D4\u05DD"," \u0986\u09DF","\u09C7\u09B8\u09CD\u0995"," onu\u0148"," \u770B"," \u0930\u0916\u093E"," Insight","\u062F\u064A\u0648",'(",",'," biased","\u0941\u0933\u0947","NBA","\u201CAs"," t\xF6rt"," \u0432\u043E\u043A\u0440\u0443\u0433"," Gad",".buf","ampang"," incompet"," \u0D2A\u0D32","isque"," \u6D77\u5357"," chorus","nus"," handbook"," Ner"," Mkuu"," \u0632\u0645\u06CC\u0646\u0647","sce"," lawa","\uD2C0"," incremento","\u03B5\u03B9\u03C4\u03BF\u03C5\u03C1\u03B3"," Risiko"," Nationale"," iwwer",` ).
1810
1814
 
1811
- `,"iplina","\u04AF\u04AF\u0445","ignty","tracker"," Absch","bett","adto"," Activation","\u2019l"," conjunt"," mounts","\u9700\u6C42"," Alleg","(binding"," banget",")Math"," metu","\u4E9A\u6D32\u7CBE\u54C1"," \u0438\u043C\u0435\u043D\u0438"," \u043F\u043E\u043C\u043E\u0447\u044C"," convierte"," \u0AA8\u0AB5\u0ABE"," psychologist","\u03C3\u03BF\u03C5\u03BC\u03B5"," mitigation","Deadline","IRS","renia","\u0C41\u0C24\u0C42"," revela"," \u10DB\u10D8\u10DB\u10D3\u10D8\u10DC"," \u0622\u0633\u06CC"," apparaat"," seldom","\u0910"," gland","\u0627\u0644\u0634",";;;"," Primer","ramer"," downtime"," \u05D3\u05D0\u05E8","Chunks","\u0443\u0441\u043E\u0432"," inscription"," kjer","\u0C48\u0C24","\u0111a"," colaboradores"," portfolios","\u093E\u0930\u094D\u091F","\xEComh"," dropout","\u5B59"," daemon"," ocupa","eterangan","uj\u0105c"," dirs"],yt=[" dew"," \u0441\u0443\u043C\u043C\u0443"," reciente",".?"," Temporary","Hints"," \u05D0\u05B7\u05DC\u05E2"," \u53F0\u6E7E"," asegur\xF3","handlers"," \u0438\u0441\u0435\u043C","(normal"," Webcam","\u0627\u0644\u062A\u0627\u0644\u064A"," Kenny"," \u10E8\u10D4\u10E1\u10D0\u10D1\u10D0\u10DB\u10D8\u10E1"," l\xE4bi","letso","\u6838\u5FC3"," blant"," btw"," \u5C11\u5987"," chew","\u10D0\u10DA\u10D3","\u8BA1\u5212\u7F51","\u2019\xE9cole"," Xana"," zase"," Helena","ivariate","\u0438\u043A\u043E","(Field"," unacceptable"," probabilities","mynd"," \u043F\u043E\u0445\u0443\u0434"," \uD65C\uC6A9","exual"," piloto"," complicado"," svol","enciales"," donating","-engine",`("'`,"OMS","leton","\u0430\u043D\u043A"," \u041D\u0430\u0448"," CLICK","\u0578\u0582\u0584"," \uC54A\uC740","\u05D5\u05E0\u05EA"," \u044E\u043B"," \u0935\u093E\u0939","terminate","\uFF0C\u300C","\u0578\u0582\u0569\u0575\u0578\u0582\u0576\u056B\u0581"," \u05D1\u05E2\u05D5\u05DC\u05DD"," \u0430\u04AD\u044B\u0525"," Investor"," Brace"," erros"," bree","yre","anggan",[233,143]," payouts"," addon","\u0E31\u0E15\u0E23"," kyll\xE4"," POT"," \uD65C\uB3D9"," ukuf","\u0648\u064A\u0646","ibazo"," ])"," Dragons"," REALLY","-shop"," DBG"," \u0930\u093E\u0937\u094D\u091F\u094D\u0930\u0940\u092F"," humain","zyk","aload"," electrons"," \u0641\u0631\u0635","/questions"," \u10DB\u10DD\u10EB","\u0438\u0442\u043E\u0432","ACING"," b\u1EDFi"," per"," overleg"," li\xE9s"," especializada"," siun"," decreto",":http","\u05DB\u05E9\u05D9\u05D5"," Constructs",".IM",`#\r
1815
+ `,"iplina","\u04AF\u04AF\u0445","ignty","tracker"," Absch","bett","adto"," Activation","\u2019l"," conjunt"," mounts","\u9700\u6C42"," Alleg","(binding"," banget",")Math"," metu","\u4E9A\u6D32\u7CBE\u54C1"," \u0438\u043C\u0435\u043D\u0438"," \u043F\u043E\u043C\u043E\u0447\u044C"," convierte"," \u0AA8\u0AB5\u0ABE"," psychologist","\u03C3\u03BF\u03C5\u03BC\u03B5"," mitigation","Deadline","IRS","renia","\u0C41\u0C24\u0C42"," revela"," \u10DB\u10D8\u10DB\u10D3\u10D8\u10DC"," \u0622\u0633\u06CC"," apparaat"," seldom","\u0910"," gland","\u0627\u0644\u0634",";;;"," Primer","ramer"," downtime"," \u05D3\u05D0\u05E8","Chunks","\u0443\u0441\u043E\u0432"," inscription"," kjer","\u0C48\u0C24","\u0111a"," colaboradores"," portfolios","\u093E\u0930\u094D\u091F","\xEComh"," dropout","\u5B59"," daemon"," ocupa","eterangan","uj\u0105c"," dirs"],Ht=[" dew"," \u0441\u0443\u043C\u043C\u0443"," reciente",".?"," Temporary","Hints"," \u05D0\u05B7\u05DC\u05E2"," \u53F0\u6E7E"," asegur\xF3","handlers"," \u0438\u0441\u0435\u043C","(normal"," Webcam","\u0627\u0644\u062A\u0627\u0644\u064A"," Kenny"," \u10E8\u10D4\u10E1\u10D0\u10D1\u10D0\u10DB\u10D8\u10E1"," l\xE4bi","letso","\u6838\u5FC3"," blant"," btw"," \u5C11\u5987"," chew","\u10D0\u10DA\u10D3","\u8BA1\u5212\u7F51","\u2019\xE9cole"," Xana"," zase"," Helena","ivariate","\u0438\u043A\u043E","(Field"," unacceptable"," probabilities","mynd"," \u043F\u043E\u0445\u0443\u0434"," \uD65C\uC6A9","exual"," piloto"," complicado"," svol","enciales"," donating","-engine",`("'`,"OMS","leton","\u0430\u043D\u043A"," \u041D\u0430\u0448"," CLICK","\u0578\u0582\u0584"," \uC54A\uC740","\u05D5\u05E0\u05EA"," \u044E\u043B"," \u0935\u093E\u0939","terminate","\uFF0C\u300C","\u0578\u0582\u0569\u0575\u0578\u0582\u0576\u056B\u0581"," \u05D1\u05E2\u05D5\u05DC\u05DD"," \u0430\u04AD\u044B\u0525"," Investor"," Brace"," erros"," bree","yre","anggan",[233,143]," payouts"," addon","\u0E31\u0E15\u0E23"," kyll\xE4"," POT"," \uD65C\uB3D9"," ukuf","\u0648\u064A\u0646","ibazo"," ])"," Dragons"," REALLY","-shop"," DBG"," \u0930\u093E\u0937\u094D\u091F\u094D\u0930\u0940\u092F"," humain","zyk","aload"," electrons"," \u0641\u0631\u0635","/questions"," \u10DB\u10DD\u10EB","\u0438\u0442\u043E\u0432","ACING"," b\u1EDFi"," per"," overleg"," li\xE9s"," especializada"," siun"," decreto",":http","\u05DB\u05E9\u05D9\u05D5"," Constructs",".IM",`#\r
1812
1816
  `," \u0445\u043E\u0442\u044C"," Junk"," gesto"," interdisciplinary","\u1015\u103A","\u9EA6"," \u0531\u0580\u0581\u0561\u056D"," creams","amas\u0131"," Twig","\u043E\u0436\u0434\u0435\u043D\u0438\u0435"," \u043C\u0430\u0433\u0430\u0437\u0438\u043D"," cea"," cemetery",">?","pthread"," zacht","_PERIOD"," pearl","-rel"," \u0628\u0627\u0644\u062D","loge","\u0440\u044B\u0432","=?,","\u0627\u0626\u0647\u0627","Kap"," faig"," \u09AD\u09BE\u09AC","\u0C3E\u0C38\u0C4D",'"testing',"layers"," experi\xEAncias"," monna"," Heel","\u0A30\u0A3E","-manager"," \u0628\u0634\u0623\u0646"," reduzir"," \u0433\u043E\u0432\u043E\u0440\u0438\u0442\u044C","Elig"," dejado","Monitoring"," GTX",".ie","\u3000\u636E","\u0BBF\u0BA9\u0BCD\u0BA9"," serviced"," impeccable","Alice","qb"," concre","-task"," kommune"," \u0441\u0442\u0430\u0432\u043A\u0438","Adapt"," coste","entation"," pares","-breaking"," Tata"," \u0432\u0435\u043B\u0438\u0447"," textual","\u76D1\u542C","-mar"," infatti","ograma","\u0650\u064A"," \u0648\u0693\u0627\u0646\u062F\u06D0","\u0D15\u0D4D\u0D15\u0D3E\u0D30","Looks"," ceann"," americana"," \u043D\u043E\u0432\u043E\u0439","_STORE"," upholstery"," \u0B95\u0BA3"," ethnicity"," \u0AAA\u0ACD\u0AB2","\u05DE\u05E2\u05E8"," candidats","Favorites"," \u0AB5\u0ABF\u0AB5\u0ABF\u0AA7","onstruk","Balancer","blica","varo","\u0432\u044B\u0447\u0430\u0439"," orchestra"," \u0627\u0644\u0646\u062C"," \u09B8\u0982\u09AC\u09BE\u09A6","ilta"," \u09B9\u09AF\u09BC\u09C7\u099B\u09C7","\u03BA\u03C1\u03B1"," Yon","\u05D9\u05D0\u05DC","\xE4tta","characters","appel","-public"," bagaimana","(asset"," kommenden","laag"," comforting"," \u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043B\u044C"," *@","hift","eteilig","act\xE9r","\u06C1\u0648\u0631","aurante","abulous"," cunt"," \u0648\u063A\u064A\u0631\u0647\u0627"," cooled"," abak"," prisoner"," \u043F\u043E\u0441\u0430\u0434"," swings","birds"," D\xFCss"," \u0219","\u10D0\u10E1\u10E2","Infinity"," Sohn","\u0E08\u0E4A\u0E01"," \u09AD\u09C2"," vacancy"," ANG"," \u0627\u0644\u0645\u0642\u062F"," )("," jk"," Muito",".python","\u043E\u0440\u0430\u0442\u0438"," frontier"," vode"," organiseren"," bumps","?page","organic",".cy","\u0E32\u0E22\u0E38","\u200C\u200C","-standing","-variable"," pertenec"," \u0C1F\u0C4D\u0C30","\u053C",`*****
1813
1817
  `," kuka"," "," tu\u1ED5i","dro","\u0642\u0627\u0645\u0629","\u8B70","Quota"," Lange","samples","ographers"," \u10DB\u10D7\u10D4\u10DA\u10D8","screens",".drag","-board","leyo"," dagegen"," \u0646\u0642\u0637\u0629","\u0CB2\u0CC7"," \u0434\u0435\u0440\u0436\u0430\u0432"," sosyal"," \u0A38\u0A2E"," sv\xE6rt"," webinars","gard","\u0433\u04E1","ordo"," ghosts"," Heap"," VMware"," \u0627\u062D\u0645\u062F"," \xF3leo"," Beitr\xE4ge","_GO"," \u062A\u0631\u064A\u062F","jc"," \u0643\u062A\u0628"," WK"," Leser","\u30FC\u30D3","otov"," descuento","\uD3ED","\u65E5\u4E0A\u5348"," saad","\u094B\u0938"," yanzu"," Roo"," raster","-written"," (((("," Older"," dnia"," geni\u015F","Hace"," restit"," tasi",' ?>"><?',"\u05D9\u05DE\u05D5\u05EA"," Notebook"," \u0411\u043B\u0430\u0433"," Por\xE9m"," Zusammenhang","_special","_\u5317\u4EACpk"," Dup"," \u044D\u043A\u0438","izzling","ceptors"," supermerc"," congel"," Interpret"," \u0CA6\u0CC7\u0CB6","_WORLD","\u06AA\u0646"," pocas"," Techniques"," bmp"," Prev","atables","\uFF3C(^","estaan"," \uC790\uB3D9"," endere\xE7o"," depan"," \u0441\u043B\u043E\u0432\u0430\u043C"," \u0E17\u0E38\u0E01",".variable","\u0E2B\u0E21\u0E32\u0E22","-------------</"," \u0441\u043D\u0430"," Gr\xE2ce"," \u0645\u0627\u0631\u0633",`));
1814
1818
 
@@ -3266,58 +3270,56 @@ ${" ".repeat(e)}}`;default:return"any"}}function Fr(a){let e=["namespace functio
3266
3270
  `," ffur","-All","Constru","Retrieved"," incr\xEDveis"," \u0438\u043C\u043A\u043E"," foliga"," Balanced","\u1021\u101E"," schlechten"," \u03B1\u03BB\u03BB\u03B1\u03B3"," \u0436\u0430\u0441\u0430\u043F"," S\u01A1n","\u0438\u0440\u0430\u0438","\u10D8\u10DC\u10D4"," milioane","EMU","\u2019\xE9viter"," hyr"," encontre"," hallar"," tablas","_Long","<Cell"," interacted"," figsize"," \u10D6\u10E6"," \u0447\u043E\u0432\u0435\u043A"," Codigo"," dedica\xE7\xE3o"," stolet"," Orten","Philip"," \xE9mission","\u0E32\u0E2B\u0E25\u0E35"," bearbeiten"," mierda","holde","\u0443\u0432\u0430\u0432","<Component"," WPA","\u05E6\u05D9\u05DC\u05D5\u05DD","SSA"," Allies"," B\xE1r","_mer","_SMS"," \u0918\u0942\u092E"," Fixtures"," Bask"," \u5F90"," tradu\xE7\xE3o","blicke"," hammered"," \u0441\u04AF\u043F"," \u0431\u0438\u0433","olu\xE7\xE3o"," electricians","\u0631\u06CC\u0634\u0646"," pitsaaner"," cier"," Receita","\u9EBB\u5C06"," \u0437\u0430\u043A\u043E\u043D\u043E\u0434\u0430\u0442\u0435\u043B\u044C\u0441\u0442\u0432\u0430"," \u10DE\u10D0\u10E1\u10E3\u10EE\u10D8\u10E1\u10DB\u10D2","-operated","\u0D4A\u0D2A\u0D4D\u0D2A\u0D02"," hassles","\u093E\u0924\u0930","\u0430\u043D\u0430\u0433\u0430\u0440\u0430","\u05E0\u05D8\u05E8","Japgolly"," doeleinden"," \u043F\u0435\u0440\u0435\u0439\u0442\u0438"," temsil"," ol\xEDmp"," Spazier"," \u0627\u0644\u0633\u0645\u0627"," pressione"," fiscais","l\u0259rini"," abode"," tantric","()],","rello"," \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044E","\u5FAE\u8F6F\u96C5\u9ED1","\u0633\u0631\u0627\u0626\u064A\u0644\u064A\u0629"," uitzending","flok"," escult"," Cerro"," is\xE6r"," kobiet","uree","\u0C95\u0CCA","encha"," adhesives"," paura","\u30C3\u30D4\u30F3\u30B0","\u0E27\u0E31\u0E22"," names"," slimmer","milk"," \u0A95\u0AB0\u0AA4\u0AC0"," Cim"," \u0441\u0432\u044F\u0437\u0430\u043D","\u200C\u0C28\u0C4D"," Chauff"," vingers","\u0430\u0446\u0430\u0440\u0442"," webcast",".notice"," m\u1EB7c","Passengers"," \u05E4\u05BC\u05E8\u05D0\u05B8\u05D3\u05D5\u05E7\u05D8\u05DF","\u0430\u043C\u0435\u0442\u0440"," VBA"," \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442\u0441\u044F",`])));
3267
3271
  `," surfers"," \u05DE\u05EA\u05D0\u05D9\u05DD",`')):
3268
3272
  `,".apk","\u1EDBm"," \u05D4\u05DE\u05D6"," brincar"," AMOLED"," nate"," ayaan"," phosphorylation"," \u0985\u09AA\u09C7\u0995\u09CD\u09B7"," Eats"," Converse","\u094D\u092F\u0942\u091F\u0930","Traveler","inggi","\u05D5\u05E8\u05D2"," almoh"," \u0625\u0641\u0631\u064A\u0642\u064A\u0627"," Magazin"," Arme","\u0E23\u0E01\u0E34\u0E08"," a\u015Fk","-lines"," \u0627\u0644\u0623\u0645\u0627\u0643\u0646","\u516C\u5E73"," kv\xE4ll"," mlx"," \u092E\u0928\u094D\u0924\u094D\u0930\u0940","\u10D0\u10D5\u10D8\u10D0"," teks"," lumea"," legyen"," zwing"," boost"," J\xFA","\u5F69\u7968\u8BBA\u575B"," \u0434\u044D"," \u043E\u0448\u0438\u0431\u043E\u043A","\u0561\u056F\u0561\u0576\u056B","\u0E24\u0E29\u0E20\u0E32\u0E04\u0E21","ebwa"," tipu"," domini"," Gurgaon","combat"," Resist"," \u0930\u094B\u091C\u0917\u093E\u0930","strategie","\u0A17\u0A40","(locator","MONTH"," atlik"," \uB79C","\u0627\u0644\u0633\u064A"," rzecz"," W\xE4"," deportivos"," Facilit","-able"," evitare"," thong"," \u6D3B","\uBB34\uB8CC"," mace"," Extraordinary","\u0927\u093E"," konflik"," livelihoods"," \u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u043E\u0432"," kuitenkaan","\u5E78\u8FD0\u98DE\u8247","Corpus"," besch\xE4d"," \u05D3\u05D5\u05D3"," dentant"," nweta"," heath"," \u0936\u0941\u0915\u094D\u0930\u092C\u093E\u0930"," mnemonic",".Filters",`','".$`," \u0905\u0938\u094D\u0924","isite"," asawa","\u5E74\u6708"," gotas"," \u0C2A\u0C28\u0C3F\u0C1A","Dek"," Pact","'agence","fei\xE7o"," B\xF6yle","venteen","notif"," \u0410\u043D\u0434\u0440\u0435\u0439","\u591A\u5E74","mittedly","\u8CA1\u5E03"," \u043A\u043E\u043C\u043F\u0430\u043A\u0442","trk","\u0928\u094D\u0926\u094D\u0930\u0940\u092F"," miesto"," Kait"," \u0CAC\u0CB8"," spec"," Injector"," logarith","entions"," \u0447\u0435\u043B","Collateral"," confes","\u093F\u0939\u0930"," sufri\xF3","CRI"," tuge","urllib"," k\u013C"," verpleeg"," application's","(Constructor","\u09BE\u09B2\u09BE"," vulputate"," \u043E\u043F\u0443\u0445"," Nordrhein","allage","\xEDsimas","ornado","\u0438\u0434\u0435\u0440","m\xE9nyek","Qua"," pelicula","\uC131\uACFC","\u3011-"," hemi"," touristes"," absentee"," Nether",".PAGE"," i\u015Fg\xE4r"," efectivos"," saav"," ","flashdata"," sembler"," ikuku"," \u099F\u09BE\u0987",` \u201D
3269
- `,"\u5F69\u7968\u5E73\u53F0\u5F00\u6237","\u65C1",".\u0413","uckles"," \u0627\u0644\u062E\u0627\u0631","\u0432\u043E\u043B\u044C"," \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436",".gradient"," ebile"," Athlete"," \u0442\u04B1\u0440\u0493\u0430\u043D"," Syrie",".processing"," Consultancy"," thrills","\u0642\u0631\u0627\u0621","(varargin","k\xFCnfte"," \u5F6D","-knit","riedenheit"," t\xE4nka","']//","udies","hacer"," Th\xE9\xE2tre","av\u7535\u5F71"," Armada","-techn","ibris","veli"," razloga","-Hop"," \u05DE\u05D7\u05D3\u05E9"," Bloggers"," controversies"," \u0C1A\u0C30\u0C4D\u0C2F"," \u0D2A\u0D4D\u0D30\u0D2E\u0D41\u0D16","_unc","werfen"," \u043B\u043E\u043C"," \u043F\u043E\u043A\u0443\u043F\u0430\u0442\u0435\u043B\u0435\u0439"," \u0433\u043B\u0430\u0437\u0430\u043C\u0438"," \u05D1\u05E2\u05D5\u05D3"," nanot"," ws"," \u043A\u0435\u0437\u0434\u0435\u0441","):("," Produit","Aircraft","iffen"," patrones"," par\xE2metros","Cursos"," cocos"],vt=kt.concat(yt);kt.length=0;yt.length=0;var rs=ft.getEncodingApi("o200k_base",()=>vt),{decode:ql,decodeAsyncGenerator:Ul,decodeGenerator:Hl,encode:Vl,encodeGenerator:Wl,isWithinTokenLimit:Kl,countTokens:wt,encodeChat:$l,encodeChatGenerator:Jl,vocabularySize:Yl,setMergeCacheSize:Xl,clearMergeCache:Ql,estimateCost:Zl}=rs;var ss=/[A-Za-z]+|\d+|[^\sA-Za-z\d]/g;function Xn(a,e=4){if(!a)return 0;let n=a.length/e,i=0;for(let r of a.match(ss)??[]){let t=/^[A-Za-z]/.test(r)?6:/^\d/.test(r)?3:1;i+=Math.max(1,Math.ceil(r.length/t))}return Math.max(1,Math.round(Math.max(n,i)))}function Ce(a,e){if(!a)return{tokens:0,exact:e.tokenizer!=="heuristic"};if(e.tokenizer==="o200k")try{return{tokens:wt(a),exact:!0}}catch{}return{tokens:Xn(a,e.charsPerToken),exact:!1}}var os={debugging:[/\b(error|exception|traceback|stack ?trace|crash(es|ed|ing)?|segfault|undefined is not|cannot read propert|null pointer|stack overflow)\b/],coding:[/\b(code|function|method|class|script|refactor|implement|api|endpoint|regex|sql|query|unit tests?|typescript|javascript|python|java|rust|golang|c\+\+|react|component|compile|deploy)\b/],editing:[/\b(proofread|rewrite|rephrase|reword|edit|polish|improve|fix (the )?grammar|make (it|this) (sound|more|less)|tone of)\b/],summarizing:[/\b(summari[sz]e|summary|tl;?dr|key (points|takeaways)|condense|recap|gist)\b/],translation:[/\btranslat(e|ion)\b|\b(in|into) (english|hindi|spanish|french|german|japanese|chinese|arabic|portuguese|italian|korean|russian)\b/],analysis:[/\b(analy[sz]e|analysis|dataset|csv|spreadsheet|table|chart|trend|average|median|correlat|statistics?|metrics?)\b/],brainstorming:[/\b(brainstorm|ideas? for|suggest (some|a few)|come up with|names? for|list of ideas)\b/],writing:[/\b(write|draft|compose|blog|essay|article|email|cover letter|post|story|poem|speech|announcement|outline)\b/],research:[/^(what|why|how|when|where|who|which|is|are|can|does|do|should|explain|compare|tell me)\b/,/\b(explain|difference between|compare|pros and cons|research|sources?)\b/]},ls=/\b(bug|broken|fails?|failing|doesn'?t work|not working|wrong output|fix (this|the|my|it))\b/,St=["debugging","translation","summarizing","editing","analysis","coding","brainstorming","writing","research"],cs=/```[\s\S]*?```|~~~[\s\S]*?~~~/g,Qn=/^\s*(def |class |function |const |let |var |import |from \S+ import|#include|public |private |return\b|if\s*\(|for\s*\(|while\s*\(|\}|\{|<\/?[a-z][\w-]*[ >])|;\s*$/,rn=/^\s*(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}|\[\d{2}:\d{2}:\d{2}|\[?(INFO|WARN|WARNING|ERROR|DEBUG|TRACE|FATAL)\]?\b|at .+[(:]\d+|File ".+", line \d+|Traceback \(most recent call last\)|\w+(Error|Exception)(: |$)|Caused by:)/,us=/^\s*([^,\t\n]+[,\t]){2,}[^,\t\n]+\s*$|^\s*[[{]\s*"\w+"\s*:/,ds=/\b(in|under|within|at most|max(imum)?|no more than|about|around|exactly|only)\s+\d+\s*(words?|sentences?|bullets?|bullet points|lines?|paragraphs?|points?|items?|characters?|chars?|tokens?)\b|\b(\d+|one|two|three|four|five|six|seven|eight|nine|ten)[- ](words?|sentences?|bullets?|bullet points|lines?|paragraphs?|points?|ideas?|items?)\b|\b(brief(ly)?|concise(ly)?|short(ly)?|succinct(ly)?|tl;?dr|one[- ]liner|yes or no|just the (answer|code|diff))\b/,ms=/\b(full|entire|whole|complete)\s+(file|code|script|program|document|text|essay)\b|\brewrite (the )?(whole|entire)\b/;function ps(a,e){let n=a.filter(i=>i.trim());return n.length?n.filter(i=>e.test(i)).length/n.length:0}function Da(a){let e=a.replace(/^\s+/,""),n=a.length-e.length,i=/\n\s*\n|:\s*\n/.exec(e);if(!i)return{instruction:a,material:""};let r=n+i.index+i[0].length;return{instruction:a.slice(0,r),material:a.slice(r)}}function ra(a){let e=a.split(`
3270
- `),n=a.match(cs)??[],{instruction:i,material:r}=Da(a),t=i.toLowerCase().trim(),s={hasCode:n.length>0||ps(e,Qn)>.3,hasLogs:e.filter(u=>rn.test(u)).length>=2,hasData:e.filter(u=>us.test(u)).length>=3,pastedTokens:Xn(r),hasLengthLimit:ds.test(a.toLowerCase()),asksForFullOutput:ms.test(t)},o=new Map;for(let u of St){let g=os[u],h=g.reduce((E,I)=>E+(I.test(t)?2:0),0);!h&&r&&(h=g.reduce((E,I)=>E+(I.test(r.slice(0,2e3).toLowerCase())?.5:0),0)),o.set(u,h)}(s.hasCode||s.hasLogs)&&ls.test(t)&&o.set("debugging",(o.get("debugging")??0)+2),s.hasLogs&&o.set("debugging",(o.get("debugging")??0)+2),s.hasCode&&o.set("coding",(o.get("coding")??0)+1.5),s.hasData&&o.set("analysis",(o.get("analysis")??0)+1);let l="chat",c=0;for(let u of St){let g=o.get(u)??0;g>c&&(l=u,c=g)}return{task:l,confidence:Math.min(1,c/4),signals:s}}var _t=new Set(["chat","writing","brainstorming","research"]);var gs=[["number",/\b\d+(?:[.,]\d+)*%?/g],["url",/https?:\/\/\S+/g],["code",/`[^`\n]+`/g],["quote",/"[^"\n]{1,200}"|“[^”\n]{1,200}”/g],["negation",/\b(?:not|no|never|none|nothing|nor|without|cannot|can't|don't|doesn't|didn't|won't|wouldn't|shouldn't|isn't|aren't|wasn't|mustn't)\b/gi],["constraint",/\b(?:must|only|exactly|always|avoid|at least|at most|required|mandatory|strictly|unless|except)\b/gi]];function sn(a){let e=new Map;for(let[n,i]of gs)for(let r of a.match(i)??[]){let t=`${n}:${r.toLowerCase()}`;e.set(t,(e.get(t)??0)+1)}return e}function Zn(a,e,n="count"){let i=sn(a),r=sn(e),t=[];for(let[s,o]of i)(r.get(s)??0)<(n==="count"?o:1)&&t.push(s);return{ok:t.length===0,lost:t}}function ei(a,e){let n=sn(a),i=sn(e),r={};for(let t of n.keys()){let s=t.slice(0,t.indexOf(":")),[o,l]=r[s]??[0,0];r[s]=[o+1,l+(i.has(t)?1:0)]}return r}var rc=new Set("please kindly thank thanks much lot advance hi hello hey there chatgpt claude gemini basically actually really very just simply quite literally totally definitely important worth noting note make sure order regard respect fact purpose event point time near future large number majority able wondering like love want need you your would could will can helpful assistant language model act possible mind think step breath deep take reasoning thought process work before answering answer show explain spite due lets let's the that this with for are was is it's its and".split(" "));var B=(a,e,n,i,r=!1)=>({re:new RegExp(a,"gim"),repl:e,name:n,level:i,reasoningOnly:r}),hs=[B(String.raw`\bdue to the fact that\b`,"because","wordy phrasing","light"),B(String.raw`\bin spite of the fact that\b`,"although","wordy phrasing","light"),B(String.raw`\bin the event that\b`,"if","wordy phrasing","light"),B(String.raw`\bfor the purpose of\b`,"for","wordy phrasing","light"),B(String.raw`\bin order to\b`,"to","wordy phrasing","light"),B(String.raw`\bwith (?:regard|respect) to\b`,"about","wordy phrasing","light"),B(String.raw`\bat this point in time\b`,"now","wordy phrasing","light"),B(String.raw`\bin the near future\b`,"soon","wordy phrasing","light"),B(String.raw`\ba large number of\b`,"many","wordy phrasing","light"),B(String.raw`\bthe majority of\b`,"most","wordy phrasing","light"),B(String.raw`\b(is|are) able to\b`,"can","wordy phrasing","light"),B(String.raw`\bmake sure that\b`,"ensure","wordy phrasing","light"),B(String.raw`\b(?:let'?s|please)?\s*think (?:about (?:this|it) )?step[- ]by[- ]step\b[.,]?\s*`,"","step-by-step (model already reasons)","light",!0),B(String.raw`\btake a deep breath(?: and)?[.,]?\s*`,"","step-by-step (model already reasons)","light",!0),B(String.raw`\b(?:show|explain) your (?:reasoning|thought process|work) (?:step[- ]by[- ]step )?(?:before (?:answering|you answer))[.,]?\s*`,"","step-by-step (model already reasons)","light",!0),B(String.raw`^\s*(?:hi|hello|hey)(?: there)?(?: chatgpt| claude| gemini)?[,!.]?\s*`,"","politeness","balanced"),B(String.raw`(^|[.!?]\s+)(?:could|can|would|will) you (?:please )?(?:kindly )?([^.!?\n]*)\?`,"$1$2.","politeness","balanced"),B(String.raw`(^|[.!?]\s+)(?:could|can|would|will) you (?:please )?(?:kindly )?`,"$1","politeness","balanced"),B(String.raw`\bi would (?:really )?(?:like|love) (?:for )?you to\b\s*`,"","politeness","balanced"),B(String.raw`\bi (?:want|need) you to\b\s*`,"","politeness","balanced"),B(String.raw`\bplease\b,?\s*`,"","politeness","balanced"),B(String.raw`\bkindly\b\s*`,"","politeness","balanced"),B(String.raw`\bthank you(?: so much| very much| a lot)?(?: in advance)?[.!]?`,"","politeness","balanced"),B(String.raw`\bthanks(?: so much| very much| a lot)?(?: in advance)?[.!]?`,"","politeness","balanced"),B(String.raw`\b(?:it is|it's) (?:important|worth noting) (?:to note )?that\b\s*`,"","filler","balanced"),B(String.raw`\b(?:please )?note that\b\s*`,"","filler","balanced"),B(String.raw`\b(?:you are|act as|as) (?:an?|my) (?:ai|large language model|helpful assistant|ai assistant)[,.]?\s*`,"","filler","balanced"),B(String.raw`\bi was wondering if\b\s*`,"","filler","balanced"),B(String.raw`(?<!\bnot )\b(?:basically|actually|really|very|just|simply|quite|literally|totally|definitely)\b\s*`,"","hedges","aggressive"),B(String.raw`\b(?:if possible|if you can|if you don't mind)\b[,.]?\s*`,"","hedges","aggressive")],on={light:0,balanced:1,aggressive:2},bs=/(```[\s\S]*?```|~~~[\s\S]*?~~~)/,fs=new RegExp(["`[^`\\n]+`","https?:\\/\\/\\S+","<([A-Za-z][\\w-]*)[^>]*>[\\s\\S]*?<\\/\\1>",'"""[\\s\\S]*?"""'].join("|"),"g");function ks(a){return/^\s*>/.test(a)||/^\s{4,}\S/.test(a)||Qn.test(a)||rn.test(a)}function ys(a,e){return e&&/^[A-Z]/.test(a)?e[0].toUpperCase()+e.slice(1):e}function vs(a,e,n){for(let i of hs){if(on[i.level]>on[e.level]||i.reasoningOnly&&!e.profile.reasoning)continue;i.re.lastIndex=0;let r=a.replace(i.re,(...t)=>{let s=t[0],o=t.slice(1,-2),l=i.repl.replace(/\$(\d)/g,(u,g)=>o[Number(g)-1]??""),c=i.repl.startsWith("$1")?o[0]??"":"";return c+ys(s.slice(c.length),l.slice(c.length))});r!==a&&(n.push(i.name),a=r)}return a}function ws(a,e){let n=new Set;return a.split(`
3273
+ `,"\u5F69\u7968\u5E73\u53F0\u5F00\u6237","\u65C1",".\u0413","uckles"," \u0627\u0644\u062E\u0627\u0631","\u0432\u043E\u043B\u044C"," \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436",".gradient"," ebile"," Athlete"," \u0442\u04B1\u0440\u0493\u0430\u043D"," Syrie",".processing"," Consultancy"," thrills","\u0642\u0631\u0627\u0621","(varargin","k\xFCnfte"," \u5F6D","-knit","riedenheit"," t\xE4nka","']//","udies","hacer"," Th\xE9\xE2tre","av\u7535\u5F71"," Armada","-techn","ibris","veli"," razloga","-Hop"," \u05DE\u05D7\u05D3\u05E9"," Bloggers"," controversies"," \u0C1A\u0C30\u0C4D\u0C2F"," \u0D2A\u0D4D\u0D30\u0D2E\u0D41\u0D16","_unc","werfen"," \u043B\u043E\u043C"," \u043F\u043E\u043A\u0443\u043F\u0430\u0442\u0435\u043B\u0435\u0439"," \u0433\u043B\u0430\u0437\u0430\u043C\u0438"," \u05D1\u05E2\u05D5\u05D3"," nanot"," ws"," \u043A\u0435\u0437\u0434\u0435\u0441","):("," Produit","Aircraft","iffen"," patrones"," par\xE2metros","Cursos"," cocos"],Vt=Ut.concat(Ht);Ut.length=0;Ht.length=0;var Ds=qt.getEncodingApi("o200k_base",()=>Vt),{decode:_c,decodeAsyncGenerator:Ec,decodeGenerator:Ac,encode:Tc,encodeGenerator:Cc,isWithinTokenLimit:Rc,countTokens:Wt,encodeChat:Pc,encodeChatGenerator:zc,vocabularySize:Ic,setMergeCacheSize:xc,clearMergeCache:Mc,estimateCost:jc}=Ds;var Ns=/[A-Za-z]+|\d+|[^\sA-Za-z\d]/g;function gi(a,e=4){if(!a)return 0;let n=a.length/e,i=0;for(let r of a.match(Ns)??[]){let t=/^[A-Za-z]/.test(r)?6:/^\d/.test(r)?3:1;i+=Math.max(1,Math.ceil(r.length/t))}return Math.max(1,Math.round(Math.max(n,i)))}function Me(a,e){if(!a)return{tokens:0,exact:e.tokenizer!=="heuristic"};if(e.tokenizer==="o200k")try{return{tokens:Wt(a),exact:!0}}catch{}return{tokens:gi(a,e.charsPerToken),exact:!1}}var Ls={debugging:[/\b(error|exception|traceback|stack ?trace|crash(es|ed|ing)?|segfault|undefined is not|cannot read propert|null pointer|stack overflow)\b/],coding:[/\b(code|function|method|class|script|refactor|implement|api|endpoint|regex|sql|query|unit tests?|typescript|javascript|python|java|rust|golang|c\+\+|react|component|compile|deploy)\b/],editing:[/\b(proofread|rewrite|rephrase|reword|edit|polish|improve|fix (the )?grammar|make (it|this) (sound|more|less)|tone of)\b/],summarizing:[/\b(summari[sz]e|summary|tl;?dr|key (points|takeaways)|condense|recap|gist)\b/],translation:[/\btranslat(e|ion)\b|\b(in|into) (english|hindi|spanish|french|german|japanese|chinese|arabic|portuguese|italian|korean|russian)\b/],analysis:[/\b(analy[sz]e|analysis|dataset|csv|spreadsheet|table|chart|trend|average|median|correlat|statistics?|metrics?)\b/],brainstorming:[/\b(brainstorm|ideas? for|suggest (some|a few)|come up with|names? for|list of ideas)\b/],writing:[/\b(write|draft|compose|blog|essay|article|email|cover letter|post|story|poem|speech|announcement|outline)\b/],research:[/^(what|why|how|when|where|who|which|is|are|can|does|do|should|explain|compare|tell me)\b/,/\b(explain|difference between|compare|pros and cons|research|sources?)\b/]},Bs=/\b(bug|broken|fails?|failing|doesn'?t work|not working|wrong output|fix (this|the|my|it))\b/,Kt=["debugging","translation","summarizing","editing","analysis","coding","brainstorming","writing","research"],Fs=/```[\s\S]*?```|~~~[\s\S]*?~~~/g,hi=/^\s*(def |class |function |const |let |var |import |from \S+ import|#include|public |private |return\b|if\s*\(|for\s*\(|while\s*\(|\}|\{|<\/?[a-z][\w-]*[ >])|;\s*$/,wn=/^\s*(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}|\[\d{2}:\d{2}:\d{2}|\[?(INFO|WARN|WARNING|ERROR|DEBUG|TRACE|FATAL)\]?\b|at .+[(:]\d+|File ".+", line \d+|Traceback \(most recent call last\)|\w+(Error|Exception)(: |$)|Caused by:)/,Gs=/^\s*([^,\t\n]+[,\t]){2,}[^,\t\n]+\s*$|^\s*[[{]\s*"\w+"\s*:/,qs=/\b(in|under|within|at most|max(imum)?|no more than|about|around|exactly|only)\s+\d+\s*(words?|sentences?|bullets?|bullet points|lines?|paragraphs?|points?|items?|characters?|chars?|tokens?)\b|\b(\d+|one|two|three|four|five|six|seven|eight|nine|ten)[- ](words?|sentences?|bullets?|bullet points|lines?|paragraphs?|points?|ideas?|items?)\b|\b(brief(ly)?|concise(ly)?|short(ly)?|succinct(ly)?|tl;?dr|one[- ]liner|yes or no|just the (answer|code|diff))\b/,Us=/\b(full|entire|whole|complete)\s+(file|code|script|program|document|text|essay)\b|\brewrite (the )?(whole|entire)\b/;function Hs(a,e){let n=a.filter(i=>i.trim());return n.length?n.filter(i=>e.test(i)).length/n.length:0}function Va(a){let e=a.replace(/^\s+/,""),n=a.length-e.length,i=/\n\s*\n|:\s*\n/.exec(e);if(!i)return{instruction:a,material:""};let r=n+i.index+i[0].length;return{instruction:a.slice(0,r),material:a.slice(r)}}function pa(a){let e=a.split(`
3274
+ `),n=a.match(Fs)??[],{instruction:i,material:r}=Va(a),t=i.toLowerCase().trim(),s={hasCode:n.length>0||Hs(e,hi)>.3,hasLogs:e.filter(u=>wn.test(u)).length>=2,hasData:e.filter(u=>Gs.test(u)).length>=3,pastedTokens:gi(r),hasLengthLimit:qs.test(a.toLowerCase()),asksForFullOutput:Us.test(t)},o=new Map;for(let u of Kt){let g=Ls[u],h=g.reduce((y,I)=>y+(I.test(t)?2:0),0);!h&&r&&(h=g.reduce((y,I)=>y+(I.test(r.slice(0,2e3).toLowerCase())?.5:0),0)),o.set(u,h)}(s.hasCode||s.hasLogs)&&Bs.test(t)&&o.set("debugging",(o.get("debugging")??0)+2),s.hasLogs&&o.set("debugging",(o.get("debugging")??0)+2),s.hasCode&&o.set("coding",(o.get("coding")??0)+1.5),s.hasData&&o.set("analysis",(o.get("analysis")??0)+1);let l="chat",c=0;for(let u of Kt){let g=o.get(u)??0;g>c&&(l=u,c=g)}return{task:l,confidence:Math.min(1,c/4),signals:s}}var $t=new Set(["chat","writing","brainstorming","research"]);var Vs=[["number",/\b\d+(?:[.,]\d+)*%?/g],["url",/https?:\/\/\S+/g],["code",/`[^`\n]+`/g],["quote",/"[^"\n]{1,200}"|“[^”\n]{1,200}”/g],["negation",/\b(?:not|no|never|none|nothing|nor|without|cannot|can't|don't|doesn't|didn't|won't|wouldn't|shouldn't|isn't|aren't|wasn't|mustn't)\b/gi],["constraint",/\b(?:must|only|exactly|always|avoid|at least|at most|required|mandatory|strictly|unless|except)\b/gi]];function Sn(a){let e=new Map;for(let[n,i]of Vs)for(let r of a.match(i)??[]){let t=`${n}:${r.toLowerCase()}`;e.set(t,(e.get(t)??0)+1)}return e}function fi(a,e,n="count"){let i=Sn(a),r=Sn(e),t=[];for(let[s,o]of i)(r.get(s)??0)<(n==="count"?o:1)&&t.push(s);return{ok:t.length===0,lost:t}}function bi(a,e){let n=Sn(a),i=Sn(e),r={};for(let t of n.keys()){let s=t.slice(0,t.indexOf(":")),[o,l]=r[s]??[0,0];r[s]=[o+1,l+(i.has(t)?1:0)]}return r}var Fc=new Set("please kindly thank thanks much lot advance hi hello hey there chatgpt claude gemini basically actually really very just simply quite literally totally definitely important worth noting note make sure order regard respect fact purpose event point time near future large number majority able wondering like love want need you your would could will can helpful assistant language model act possible mind think step breath deep take reasoning thought process work before answering answer show explain spite due lets let's the that this with for are was is it's its and".split(" "));var U=(a,e,n,i,r=!1)=>({re:new RegExp(a,"gim"),repl:e,name:n,level:i,reasoningOnly:r}),Ws=[U(String.raw`\bdue to the fact that\b`,"because","wordy phrasing","light"),U(String.raw`\bin spite of the fact that\b`,"although","wordy phrasing","light"),U(String.raw`\bin the event that\b`,"if","wordy phrasing","light"),U(String.raw`\bfor the purpose of\b`,"for","wordy phrasing","light"),U(String.raw`\bin order to\b`,"to","wordy phrasing","light"),U(String.raw`\bwith (?:regard|respect) to\b`,"about","wordy phrasing","light"),U(String.raw`\bat this point in time\b`,"now","wordy phrasing","light"),U(String.raw`\bin the near future\b`,"soon","wordy phrasing","light"),U(String.raw`\ba large number of\b`,"many","wordy phrasing","light"),U(String.raw`\bthe majority of\b`,"most","wordy phrasing","light"),U(String.raw`\b(is|are) able to\b`,"can","wordy phrasing","light"),U(String.raw`\bmake sure that\b`,"ensure","wordy phrasing","light"),U(String.raw`\b(?:let'?s|please)?\s*think (?:about (?:this|it) )?step[- ]by[- ]step\b[.,]?\s*`,"","step-by-step (model already reasons)","light",!0),U(String.raw`\btake a deep breath(?: and)?[.,]?\s*`,"","step-by-step (model already reasons)","light",!0),U(String.raw`\b(?:show|explain) your (?:reasoning|thought process|work) (?:step[- ]by[- ]step )?(?:before (?:answering|you answer))[.,]?\s*`,"","step-by-step (model already reasons)","light",!0),U(String.raw`^\s*(?:hi|hello|hey)(?: there)?(?: chatgpt| claude| gemini)?[,!.]?\s*`,"","politeness","balanced"),U(String.raw`(^|[.!?]\s+)(?:could|can|would|will) you (?:please )?(?:kindly )?([^.!?\n]*)\?`,"$1$2.","politeness","balanced"),U(String.raw`(^|[.!?]\s+)(?:could|can|would|will) you (?:please )?(?:kindly )?`,"$1","politeness","balanced"),U(String.raw`\bi would (?:really )?(?:like|love) (?:for )?you to\b\s*`,"","politeness","balanced"),U(String.raw`\bi (?:want|need) you to\b\s*`,"","politeness","balanced"),U(String.raw`\bplease\b,?\s*`,"","politeness","balanced"),U(String.raw`\bkindly\b\s*`,"","politeness","balanced"),U(String.raw`\bthank you(?: so much| very much| a lot)?(?: in advance)?[.!]?`,"","politeness","balanced"),U(String.raw`\bthanks(?: so much| very much| a lot)?(?: in advance)?[.!]?`,"","politeness","balanced"),U(String.raw`\b(?:it is|it's) (?:important|worth noting) (?:to note )?that\b\s*`,"","filler","balanced"),U(String.raw`\b(?:please )?note that\b\s*`,"","filler","balanced"),U(String.raw`\b(?:you are|act as|as) (?:an?|my) (?:ai|large language model|helpful assistant|ai assistant)[,.]?\s*`,"","filler","balanced"),U(String.raw`\bi was wondering if\b\s*`,"","filler","balanced"),U(String.raw`(?<!\bnot )\b(?:basically|actually|really|very|just|simply|quite|literally|totally|definitely)\b\s*`,"","hedges","aggressive"),U(String.raw`\b(?:if possible|if you can|if you don't mind)\b[,.]?\s*`,"","hedges","aggressive")],_n={light:0,balanced:1,aggressive:2},Ks=/(```[\s\S]*?```|~~~[\s\S]*?~~~)/,$s=new RegExp(["`[^`\\n]+`","https?:\\/\\/\\S+","<([A-Za-z][\\w-]*)[^>]*>[\\s\\S]*?<\\/\\1>",'"""[\\s\\S]*?"""'].join("|"),"g");function Js(a){return/^\s*>/.test(a)||/^\s{4,}\S/.test(a)||hi.test(a)||wn.test(a)}function Ys(a,e){return e&&/^[A-Z]/.test(a)?e[0].toUpperCase()+e.slice(1):e}function Xs(a,e,n){for(let i of Ws){if(_n[i.level]>_n[e.level]||i.reasoningOnly&&!e.profile.reasoning)continue;i.re.lastIndex=0;let r=a.replace(i.re,(...t)=>{let s=t[0],o=t.slice(1,-2),l=i.repl.replace(/\$(\d)/g,(u,g)=>o[Number(g)-1]??""),c=i.repl.startsWith("$1")?o[0]??"":"";return c+Ys(s.slice(c.length),l.slice(c.length))});r!==a&&(n.push(i.name),a=r)}return a}function Qs(a,e){let n=new Set;return a.split(`
3271
3275
  `).map(i=>i.split(/(?<=[.!?])\s+/).filter(r=>{let t=r.replace(/\W+/g," ").trim().toLowerCase();return t.split(" ").length<4?!0:n.has(t)?(e.push("repeated sentence"),!1):(n.add(t),!0)}).join(" ")).join(`
3272
- `)}function Ss(a){return a.replace(/[ \t]+/g," ").replace(/ +([,.;:!?])/g,"$1").replace(/([,;:])(?=[.!?])/g,"").replace(/^[ ,;:]+/gm,"").replace(/ +$/gm,"").replace(/\n{3,}/g,`
3276
+ `)}function Zs(a){return a.replace(/[ \t]+/g," ").replace(/ +([,.;:!?])/g,"$1").replace(/([,;:])(?=[.!?])/g,"").replace(/^[ ,;:]+/gm,"").replace(/ +$/gm,"").replace(/\n{3,}/g,`
3273
3277
 
3274
- `).replace(/(^|[.!?]\s+)([a-z])/gm,(e,n,i)=>n+i.toUpperCase())}function Et(a,e,n){if(!a.trim())return a;let i=a.slice(0,a.length-a.trimStart().length),r=a.slice(a.trimEnd().length),t=[],s=u=>`\0${t.push(u)-1}\0`,o=a.trim().replace(fs,s);o=o.split(`
3275
- `).map(u=>ks(u)?s(u):u).join(`
3276
- `),on[e.level]>=on.balanced&&(o=ws(o,n));let l=o,c=[];for(o=Ss(vs(o,e,c)),Zn(l,o).ok?n.push(...c):o=l;/\u0000\d+\u0000/.test(o);)o=o.replace(/\u0000(\d+)\u0000/g,(u,g)=>t[Number(g)]);return i+o+r}var Ct=/^\s*at .*(node_modules|node:internal|internal\/|java\.base|java\.|javax\.|jdk\.internal|sun\.|org\.springframework|org\.apache|kotlin\.|scala\.|<anonymous>)|^\s*File ".*(site-packages|dist-packages|lib\/python\d|\/usr\/lib)/,_s=a=>a.replace(/\d{4}-\d{2}-\d{2}[T ][\d:.,]+Z?/g,"<ts>").replace(/\b0x[0-9a-f]+\b/gi,"<hex>").replace(/\d+/g,"#").trim();function At(a,e,n){let i=a.split(`
3277
- `),r=[];for(let o=0;o<i.length;){let l=o,c=0;for(;l<i.length&&Ct.test(i[l]);)l+=/^\s*File "/.test(i[l])&&l+1<i.length&&/^\s{4,}\S/.test(i[l+1])&&!/^\s*(File|at) /.test(i[l+1])?2:1,c++;if(c>=3){let u=/^\s*/.exec(i[o])[0];r.push(`${u}... ${c} library frames omitted`),n.push("library stack frames"),o=l}else r.push(i[o]),o++}let t=e==="aggressive"?_s:o=>o,s=[];for(let o=0;o<r.length;){let l=o+1;for(;l<r.length&&r[o].trim()&&t(r[l])===t(r[o]);)l++;s.push(r[o]),l-o>=3?(s.push(`... same line repeated ${l-o-1} more times`),n.push("repeated log lines")):s.push(...r.slice(o+1,l)),o=l}return s.join(`
3278
- `)}function Tt(a){let e=a.split(`
3279
- `).filter(n=>n.trim());return e.length>=3&&e.filter(n=>rn.test(n)||Ct.test(n)).length/e.length>=.4}function Es(a,e){let n=/^(?:```|~~~)\s*([\w+-]*)/.exec(a)?.[1]?.toLowerCase()??"",i=a.replace(/^(?:```|~~~).*\n?/,"");if(/^(md|markdown|diff|patch|text|txt)$/.test(n)||/"""|'''|`[^`\n]*\n|<<-?\s*['"]?\w+/.test(i))return a;let r=a.replace(/[ \t]+$/gm,"").replace(/\n{4,}/g,`
3278
+ `).replace(/(^|[.!?]\s+)([a-z])/gm,(e,n,i)=>n+i.toUpperCase())}function Jt(a,e,n){if(!a.trim())return a;let i=a.slice(0,a.length-a.trimStart().length),r=a.slice(a.trimEnd().length),t=[],s=u=>`\0${t.push(u)-1}\0`,o=a.trim().replace($s,s);o=o.split(`
3279
+ `).map(u=>Js(u)?s(u):u).join(`
3280
+ `),_n[e.level]>=_n.balanced&&(o=Qs(o,n));let l=o,c=[];for(o=Zs(Xs(o,e,c)),fi(l,o).ok?n.push(...c):o=l;/\u0000\d+\u0000/.test(o);)o=o.replace(/\u0000(\d+)\u0000/g,(u,g)=>t[Number(g)]);return i+o+r}var Qt=/^\s*at .*(node_modules|node:internal|internal\/|java\.base|java\.|javax\.|jdk\.internal|sun\.|org\.springframework|org\.apache|kotlin\.|scala\.|<anonymous>)|^\s*File ".*(site-packages|dist-packages|lib\/python\d|\/usr\/lib)/,eo=a=>a.replace(/\d{4}-\d{2}-\d{2}[T ][\d:.,]+Z?/g,"<ts>").replace(/\b0x[0-9a-f]+\b/gi,"<hex>").replace(/\d+/g,"#").trim();function Yt(a,e,n){let i=a.split(`
3281
+ `),r=[];for(let o=0;o<i.length;){let l=o,c=0;for(;l<i.length&&Qt.test(i[l]);)l+=/^\s*File "/.test(i[l])&&l+1<i.length&&/^\s{4,}\S/.test(i[l+1])&&!/^\s*(File|at) /.test(i[l+1])?2:1,c++;if(c>=3){let u=/^\s*/.exec(i[o])[0];r.push(`${u}... ${c} library frames omitted`),n.push("library stack frames"),o=l}else r.push(i[o]),o++}let t=e==="aggressive"?eo:o=>o,s=[];for(let o=0;o<r.length;){let l=o+1;for(;l<r.length&&r[o].trim()&&t(r[l])===t(r[o]);)l++;s.push(r[o]),l-o>=3?(s.push(`... same line repeated ${l-o-1} more times`),n.push("repeated log lines")):s.push(...r.slice(o+1,l)),o=l}return s.join(`
3282
+ `)}function Xt(a){let e=a.split(`
3283
+ `).filter(n=>n.trim());return e.length>=3&&e.filter(n=>wn.test(n)||Qt.test(n)).length/e.length>=.4}function ao(a,e){let n=/^(?:```|~~~)\s*([\w+-]*)/.exec(a)?.[1]?.toLowerCase()??"",i=a.replace(/^(?:```|~~~).*\n?/,"");if(/^(md|markdown|diff|patch|text|txt)$/.test(n)||/"""|'''|`[^`\n]*\n|<<-?\s*['"]?\w+/.test(i))return a;let r=a.replace(/[ \t]+$/gm,"").replace(/\n{4,}/g,`
3280
3284
 
3281
- `);return r!==a&&e.push("whitespace in code"),r}function Ke(a,e){let n=[],{instruction:i}=Da(a),r=i.length,t=e.task==="debugging"&&e.level!=="light",s=0,o=[];for(let[g,h]of a.split(bs).entries()){let E=s;if(s+=h.length,g%2===1){o.push(t&&Tt(h)?At(h,e.level,n):e.level==="light"?h:Es(h,n));continue}let I=h.slice(0,Math.max(0,r-E)),S=h.slice(I.length),N=S;t&&Tt(S)?N=At(S,e.level,n):_t.has(e.task)&&(N=Et(S,e,n)),o.push(Et(I,e,n)+N)}let l=o.join(""),c=Ce(a,e.profile).tokens,u=Ce(l,e.profile).tokens;return u>=c||!l.trim()?{text:a,rules:[],originalTokens:c,tokens:c,saved:0}:{text:l,rules:[...new Set(n)],originalTokens:c,tokens:u,saved:c-u}}function As(a,e="input"){let n=a.pricing;return n?(e==="output"?n.outputPerMTok:e==="cached"?n.cachedInputPerMTok??n.inputPerMTok:n.inputPerMTok)/1e6:null}function sa(a,e,n="input"){let i=As(e,n);return i===null?null:a*i}function Na(a,e,n="input"){let i=sa(a,e,n);return{tokens:a,usd:i,usdPer1k:i===null?null:i*1e3}}var me=a=>a,te={"gpt-astra":me({id:"gpt-astra",label:"GPT-6 Astra",family:"openai",contextWindow:105e4,tokenizer:"heuristic",charsPerToken:4.2,reasoning:!0,pricing:{inputPerMTok:10,outputPerMTok:50}}),"gpt-reasoning":me({id:"gpt-reasoning",label:"GPT (thinking)",family:"openai",contextWindow:196e3,tokenizer:"o200k",charsPerToken:4.2,reasoning:!0,lighterAlternative:"the Instant / non-thinking model",pricing:{inputPerMTok:5,outputPerMTok:30,cachedInputPerMTok:.5}}),gpt:me({id:"gpt",label:"GPT",family:"openai",contextWindow:128e3,tokenizer:"o200k",charsPerToken:4.2,reasoning:!1,pricing:{inputPerMTok:2.5,outputPerMTok:15,cachedInputPerMTok:.25}}),"claude-fable":me({id:"claude-fable",label:"Claude Fable",family:"anthropic",contextWindow:1e6,tokenizer:"heuristic",charsPerToken:3.5,reasoning:!0,notes:["Claude reads XML-style tags well: wrap pasted material in <doc>\u2026</doc> instead of explaining it."],pricing:{inputPerMTok:10,outputPerMTok:50,cachedInputPerMTok:.25}}),"claude-opus":me({id:"claude-opus",label:"Claude Opus",family:"anthropic",contextWindow:2e5,tokenizer:"heuristic",charsPerToken:3.5,reasoning:!1,lighterAlternative:"Sonnet or Haiku",notes:["Claude reads XML-style tags well: wrap pasted material in <doc>\u2026</doc> instead of explaining it."],pricing:{inputPerMTok:4,outputPerMTok:20,cachedInputPerMTok:.2}}),"claude-sonnet":me({id:"claude-sonnet",label:"Claude Sonnet",family:"anthropic",contextWindow:2e5,tokenizer:"heuristic",charsPerToken:3.5,reasoning:!1,lighterAlternative:"Haiku",notes:["Claude reads XML-style tags well: wrap pasted material in <doc>\u2026</doc> instead of explaining it."],pricing:{inputPerMTok:2,outputPerMTok:10,cachedInputPerMTok:.2}}),"claude-haiku":me({id:"claude-haiku",label:"Claude Haiku",family:"anthropic",contextWindow:2e5,tokenizer:"heuristic",charsPerToken:3.5,reasoning:!1,pricing:{inputPerMTok:.1,outputPerMTok:.5,cachedInputPerMTok:.01}}),"gemini-pro":me({id:"gemini-pro",label:"Gemini Pro",family:"google",contextWindow:1e6,tokenizer:"heuristic",charsPerToken:4,reasoning:!0,lighterAlternative:"Flash",pricing:{inputPerMTok:2,outputPerMTok:12,cachedInputPerMTok:.2,longContext:{aboveTokens:2e5,inputPerMTok:4,outputPerMTok:18}}}),"gemini-flash":me({id:"gemini-flash",label:"Gemini Flash",family:"google",contextWindow:1e6,tokenizer:"heuristic",charsPerToken:4,reasoning:!1,pricing:{inputPerMTok:1.5,outputPerMTok:9,cachedInputPerMTok:.15}}),deepseek:me({id:"deepseek",label:"DeepSeek",family:"deepseek",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!1,pricing:{inputPerMTok:.28,outputPerMTok:.42,cachedInputPerMTok:.028}}),"deepseek-reasoning":me({id:"deepseek-reasoning",label:"DeepSeek (thinking)",family:"deepseek",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!0,lighterAlternative:"the non-thinking mode",pricing:{inputPerMTok:.55,outputPerMTok:2.19,cachedInputPerMTok:.14}}),mistral:me({id:"mistral",label:"Mistral",family:"mistral",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!1,pricing:{inputPerMTok:2,outputPerMTok:6}}),grok:me({id:"grok",label:"Grok",family:"xai",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:4,reasoning:!1,pricing:{inputPerMTok:2,outputPerMTok:6}}),generic:me({id:"generic",label:"Unknown model",family:"other",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:4,reasoning:!1,pricing:{inputPerMTok:2,outputPerMTok:10}})},Ts=[[/\b(fable|mythos)\b/,"claude-fable"],[/\bastra\b|\bgpt[- ]?6\b/,"gpt-astra"],[/\bclaude\b.*\bopus\b|\bopus\b/,"claude-opus"],[/\bsonnet\b/,"claude-sonnet"],[/\bhaiku\b/,"claude-haiku"],[/\bgemini\b.*\bflash\b|\bflash\b/,"gemini-flash"],[/\bgemini\b.*\b(pro|ultra|deep think)\b|^\s*\d(\.\d)?\s*pro\b|\bdeep think\b/,"gemini-pro"],[/\bdeepseek\b.*\b(r1|reason|think|deepthink)|\bdeepthink\b/,"deepseek-reasoning"],[/\bdeepseek\b/,"deepseek"],[/\b(mistral|le chat|magistral|codestral)\b/,"mistral"],[/\bgrok\b/,"grok"],[/\bo[1-9](-mini|-pro)?\b|\bgpt[- ]?\S*\s*(thinking|pro)\b|\bthinking\b/,"gpt-reasoning"],[/\b(gpt|chatgpt)\b|\bgpt-?\d/,"gpt"],[/\bgemini\b/,"gemini-pro"],[/\bclaude\b/,"claude-sonnet"]];var Cs={chatgpt:"gpt",claude:"claude-sonnet",gemini:"gemini-flash",deepseek:"deepseek",mistral:"mistral",grok:"grok",generic:"generic"},La=[],Rs=a=>a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function Ps(a){let e=/^\/(.+)\/([a-z]*)$/.exec(a);return e?new RegExp(e[1],e[2].replace(/[gy]/g,"").replace(/^(?!.*i)/,"i")):new RegExp(Rs(a.toLowerCase().trim()),"i")}function ai(a){if(!a.id||!(a.contextWindow>0))throw new Error("A custom model needs an id and a positive contextWindow.");let e={id:a.id,label:a.label??a.id,family:a.family??"other",contextWindow:a.contextWindow,tokenizer:a.tokenizer??"heuristic",charsPerToken:a.charsPerToken??4,reasoning:a.reasoning??!1,lighterAlternative:a.lighterAlternative,notes:a.notes,pricing:a.pricing};ni(a.id),te[e.id]=e;for(let n of a.match?.length?a.match:[a.id])La.push([Ps(n),e.id]);return e}function ni(a){for(let e=La.length-1;e>=0;e--)La[e][1]===a&&La.splice(e,1);a in Rt?te[a]=Rt[a]:delete te[a]}var Rt={...te};function ya(a,e="generic"){let n=(a??"").toLowerCase().replace(/\s+/g," ").trim();if(n){for(let[i,r]of La)if(i.test(n))return te[r];if(e==="gemini"&&/\b(pro|deep think)\b/.test(n))return te["gemini-pro"];if(e==="gemini"&&/\bflash\b/.test(n))return te["gemini-flash"];if(e==="deepseek"&&/\b(deepthink|r1|think)/.test(n))return te["deepseek-reasoning"];for(let[i,r]of Ts)if(i.test(n))return te[r]}return te[Cs[e]??"generic"]}function Pt(a){let e=typeof a.model=="string"?ya(a.model,a.site):a.model,n=a.pricing?{...e,pricing:a.pricing}:e,i=ra(a.prompt),{tokens:r,exact:t}=Ce(a.prompt,n),s=Ra(a.conversationTokens??0,r,n,a.contextWindow),o=Wi(a.level??"auto",s),l=Ke(a.prompt,{profile:n,task:i.task,level:o}),c=Ca({profile:n,task:i.task,signals:i.signals,promptTokens:r,usage:s,text:a.prompt}),u={pricing:n.pricing,promptUsd:sa(r,n),sendUsd:sa((a.conversationTokens??0)+r,n),saved:Na(l.saved,n)},g=Object.entries(ei(a.prompt,l.text)).map(([E,[I,S]])=>`${S}/${I} ${E}s`).join(", "),h={text:l.text,tokens:l.tokens,changes:l.saved>0?l.rules.map(E=>`removed ${E}`):[],kept:g||"every instruction"};return{profile:n,task:i,promptTokens:r,exact:t,usage:s,level:o,optimized:l,tips:c,handoffPrompt:Ki(i.task),cost:u,best:h}}var Je=()=>({requests:0,errors:0,replayed:0,inputTokens:0,inputTokensBefore:0,outputTokens:0,outputTokensAvoided:0,cachedInputTokens:0,reasoningTokens:0,savedInputTokens:0,costUsd:0,costBeforeUsd:0,pricedRequests:0,checks:0,checksMatched:0,checkCostUsd:0});function zt(a,e){let n=a.pricing,i=n?.longContext,r=a.priceTier??(i?{aboveInputTokens:i.aboveTokens,inputPerMTok:i.inputPerMTok,outputPerMTok:i.outputPerMTok}:void 0);if(!n||!r||e<=r.aboveInputTokens)return n;let t=r.inputPerMTok/n.inputPerMTok;return{inputPerMTok:r.inputPerMTok,outputPerMTok:r.outputPerMTok,cachedInputPerMTok:n.cachedInputPerMTok!==void 0?n.cachedInputPerMTok*t:void 0}}function oa(a,e){let n=zt(a,e.inputTokens??0);if(!n)return 0;let i=e.cachedInputTokens??0,r=e.cacheWriteTokens??0,t=Math.max(0,(e.inputTokens??0)-i-r),s=a.family==="anthropic"?n.inputPerMTok*1.25:n.inputPerMTok;return(t*n.inputPerMTok+i*(n.cachedInputPerMTok??n.inputPerMTok)+r*s+(e.outputTokens??0)*n.outputPerMTok)/1e6}function ln(a,e,n){let i=zt(a,(e.inputTokens??0)+n);return i?(((e.inputTokens??0)+n)*i.inputPerMTok+(e.outputTokens??0)*i.outputPerMTok)/1e6:0}function ii(a,e){a.requests++,e.status>=400&&a.errors++,e.profile.pricing&&a.pricedRequests++;let n={...e.usage,inputTokens:e.usage.inputTokens??e.estimatedInput};if(e.replayed){a.replayed++,a.inputTokensBefore+=n.inputTokens,a.savedInputTokens+=n.inputTokens,a.outputTokensAvoided+=n.outputTokens??0,a.costBeforeUsd+=ln(e.profile,n,0);return}a.inputTokens+=n.inputTokens,a.inputTokensBefore+=n.inputTokens+e.savedInput,a.outputTokens+=n.outputTokens??0,a.cachedInputTokens+=n.cachedInputTokens??0,a.reasoningTokens+=n.reasoningTokens??0,a.savedInputTokens+=e.savedInput,a.costUsd+=oa(e.profile,n)*(e.priceFactor??1),a.costBeforeUsd+=ln(e.profile,n,e.savedInput)}var Is=["app","agent","model"],cn=class{rows=new Map;started=new Date().toISOString();row(e,n,i){let r=[e,n,i].join("\0"),t=this.rows.get(r);return t||this.rows.set(r,t=Je()),t}record(e){ii(this.row(e.app,e.agent,e.profile.id),e)}recordCheck(e,n,i,r,t,s=!0){let o=this.row(e,n,i.id);s&&o.checks++,s&&r&&o.checksMatched++,o.checkCostUsd+=t}snapshot(){return new Map([...this.rows].map(([e,n])=>[e,{...n}]))}grouped(e,n=this.rows){let i=new Map;for(let[r,t]of n){let s=r.split("\0"),o=e.map(c=>s[Is.indexOf(c)]).join("\0"),l=i.get(o)??Je();for(let c of Object.keys(l))l[c]+=t[c];i.set(o,l)}return[...i].map(([r,t])=>({...Object.fromEntries(e.map((s,o)=>[s,r.split("\0")[o]])),...un(t)}))}detail(e=this.rows){return this.grouped(["app","agent","model"],e)}json(e=this.rows,n=this.started){let[i]=this.grouped([],e);return{since:n,total:i??un(Je()),byTeam:this.grouped(["app"],e),byAgent:this.grouped(["app","agent"],e),byModel:this.grouped(["model"],e),byAppAndModel:this.grouped(["app","model"],e)}}prometheus(){let e=[["requests","token_lens_requests_total","Requests proxied"],["errors","token_lens_errors_total","Requests that ended in an error status"],["replayed","token_lens_replayed_total","Identical requests answered from the gateway's copy"],["inputTokens","token_lens_input_tokens_total","Input tokens sent upstream"],["inputTokensBefore","token_lens_input_tokens_before_total","Input tokens the same calls would have sent without Token Lens"],["outputTokens","token_lens_output_tokens_total","Output tokens generated"],["cachedInputTokens","token_lens_cached_input_tokens_total","Input tokens served from the provider's prompt cache"],["reasoningTokens","token_lens_reasoning_tokens_total","Hidden reasoning tokens"],["savedInputTokens","token_lens_saved_input_tokens_total","Input tokens removed by Token Lens"],["costUsd","token_lens_cost_usd_total","Spend after Token Lens, for models with pricing"],["costBeforeUsd","token_lens_cost_before_usd_total","Spend the same calls would have cost without Token Lens"],["checks","token_lens_output_checks_total","Output checks run (optimized vs original answer)"],["checksMatched","token_lens_output_checks_matched_total","Output checks where the answers matched"],["checkCostUsd","token_lens_output_check_cost_usd_total","Spend on output checks"]],n=r=>r.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n"),i=[];for(let[r,t,s]of e){i.push(`# HELP ${t} ${s}`,`# TYPE ${t} counter`);for(let[o,l]of this.rows){let[c,u,g]=o.split("\0");i.push(`${t}{app="${n(c)}",agent="${n(u)}",model="${n(g)}"} ${l[r]}`)}}return i.join(`
3282
- `)+`
3283
- `}},$e=(a,e=6)=>Math.round(a*10**e)/10**e;function un(a){let e=a.inputTokensBefore-a.inputTokens+a.outputTokensAvoided,n=a.costBeforeUsd-a.costUsd;return{...a,costUsd:$e(a.costUsd),costBeforeUsd:$e(a.costBeforeUsd),checkCostUsd:$e(a.checkCostUsd),savedTokens:e,savedTokensPct:a.inputTokensBefore+a.outputTokens+a.outputTokensAvoided?$e(e/(a.inputTokensBefore+a.outputTokens+a.outputTokensAvoided)*100,1):0,savedUsd:$e(n),savedUsdPct:a.costBeforeUsd?$e(n/a.costBeforeUsd*100,1):0,netSavedUsd:$e(n-a.checkCostUsd),outputUnchangedPct:a.checks?$e(a.checksMatched/a.checks*100,1):null,unpricedRequests:a.requests-a.pricedRequests}}import{createHash as Ls}from"node:crypto";import{createHash as xs}from"node:crypto";var dn=a=>xs("sha256").update(a).digest("hex").slice(0,24);function Ms(a){if(!(a.length<24)){if(a.readUInt32BE(0)===2303741511)return{width:a.readUInt32BE(16),height:a.readUInt32BE(20)};if(a.toString("ascii",0,3)==="GIF")return{width:a.readUInt16LE(6),height:a.readUInt16LE(8)};if(a.toString("ascii",0,4)==="RIFF"&&a.toString("ascii",8,12)==="WEBP"){let e=a.toString("ascii",12,16);if(e==="VP8X"&&a.length>=30)return{width:1+a.readUIntLE(24,3),height:1+a.readUIntLE(27,3)};if(e==="VP8 "&&a.length>=30)return{width:a.readUInt16LE(26)&16383,height:a.readUInt16LE(28)&16383};if(e==="VP8L"&&a.length>=25){let n=a.readUInt32LE(21);return{width:1+(n&16383),height:1+(n>>14&16383)}}return}if(a[0]===255&&a[1]===216){let e=2;for(;e+9<a.length;){if(a[e]!==255)return;let n=a[e+1],i=a.readUInt16BE(e+2);if(n>=192&&n<=207&&![196,200,204].includes(n))return{width:a.readUInt16BE(e+7),height:a.readUInt16BE(e+5)};e+=2+i}}}}function It(a){let e=/^data:[^;,]*;base64,(.*)$/s.exec(a);return e?Buffer.from(e[1],"base64"):void 0}function mn(a,e){let n=[],i=(t,s)=>{t.forEach((o,l)=>{if(!o||typeof o!="object")return;let c,u,g,h=I=>({type:"text",text:I});if(a==="openai-chat"&&o.type==="image_url"){let I=typeof o.image_url=="string"?o.image_url:o.image_url?.url;if(typeof I!="string")return;c=It(I),u=dn(I),g=o.image_url?.detail}else if(a==="openai-responses"&&o.type==="input_image"){if(typeof o.image_url!="string")return;c=It(o.image_url),u=dn(o.image_url),g=o.detail,h=I=>({type:"input_text",text:I})}else if(a==="anthropic"&&o.type==="image"){let I=o.source??{};if(I.type==="base64"&&typeof I.data=="string")c=Buffer.from(I.data,"base64"),u=dn(I.data);else if(typeof I.url=="string")u=dn(I.url);else return}else return a==="anthropic"&&o.type==="tool_result"&&Array.isArray(o.content)?i(o.content,s):void 0;let E=c?Ms(c):void 0;n.push({turn:s,key:u,...E,detail:g,replace:I=>t[l]=h(I)})})};return(a==="openai-responses"?Array.isArray(e?.input)?e.input:[]:Array.isArray(e?.messages)?e.messages:[]).forEach((t,s)=>{Array.isArray(t?.content)&&i(t.content,s)}),n}function ti(a,e){if(a==="openai"&&e.detail==="low")return 85;if(!e.width||!e.height)return;let n=e.width,i=e.height;if(a==="anthropic"){let s=Math.min(1,1568/Math.max(n,i),Math.sqrt(115e4/(n*i)));return Math.min(1600,Math.ceil(n*s*i*s/750))}let r=Math.min(1,2048/Math.max(n,i));n*=r,i*=r;let t=Math.min(1,768/Math.min(n,i));return n*=t,i*=t,85+170*Math.ceil(n/512)*Math.ceil(i/512)}function xt(a,e){let n=new Map,i=0,r=0;for(let t of a){let s=n.get(t.key);if(s===void 0){n.set(t.key,t.turn);continue}s!==t.turn&&(t.replace(`[Token Lens: same image as in message ${s} above]`),i+=ti(e,t)??0,r++)}return{saved:i,count:r}}var pn=["system","tools","history","tool_output","context","prompt"];function ri(a){let e=a;if(typeof e=="string")try{e=JSON.parse(e)}catch{return e}let n=i=>Array.isArray(i)?i.map(n):i&&typeof i=="object"?Object.fromEntries(Object.keys(i).sort().map(r=>[r,n(i[r])])):i;return JSON.stringify(n(e??{}))}var Ba=(a,e,n,i)=>({part:a,turn:e,get:()=>n[i],set:r=>{n[i]=r}}),gn=(a,e,n)=>({part:a,turn:e,get:()=>n});function ve(a,e,n,i,r){let t=n[i];return typeof t=="string"?[Ba(a,e,n,i)]:Array.isArray(t)?t.filter(s=>s&&typeof s=="object"&&r.includes(s.type)&&typeof s.text=="string").map(s=>Ba(a,e,s,"text")):[]}var si=a=>a.map(e=>({...e,user:!0}));function oi(a,e){for(let n=a.length-1;n>=0;n--)if(e(a[n]))return n;return-1}var li=a=>Array.isArray(a)&&a.length?[gn("tools",-1,JSON.stringify(a))]:[];function js(a){let e=Array.isArray(a.messages)?a.messages:[],n=oi(e,t=>t?.role==="assistant")+1,i=[...li(a.tools??a.functions)],r=[];return e.forEach((t,s)=>{if(!t||typeof t!="object")return;let o=["text"];if(t.role==="system"||t.role==="developer")i.push(...ve("system",-1,t,"content",o));else if(t.role==="tool"||t.role==="function")i.push(...ve("tool_output",s,t,"content",o));else if(t.role==="user")i.push(...si(ve(s>=n?"prompt":"history",s,t,"content",o)));else if(t.role==="assistant"){i.push(...ve("history",s,t,"content",o));for(let l of t.tool_calls??[])l?.function?.arguments&&i.push(gn("history",s,String(l.function.arguments))),l?.function?.name&&r.push({name:l.function.name,args:ri(l.function.arguments),turn:s})}}),{protocol:"openai-chat",model:String(a.model??""),stream:a.stream===!0,temperature:typeof a.temperature=="number"?a.temperature:void 0,maxOutputTokens:a.max_completion_tokens??a.max_tokens,refs:i,turns:e.length,toolCalls:r}}function Os(a){let e=[...li(a.tools)];typeof a.instructions=="string"&&e.push(Ba("system",-1,a,"instructions"));let n=[],i=1;if(typeof a.input=="string")e.push({...Ba("prompt",0,a,"input"),user:!0});else if(Array.isArray(a.input)){let r=a.input;i=r.length;let t=oi(r,o=>o?.role==="assistant"||o?.type==="function_call"||o?.type==="reasoning")+1,s=["input_text","output_text","text"];r.forEach((o,l)=>{!o||typeof o!="object"||(o.type==="function_call_output"?typeof o.output=="string"?e.push(Ba("tool_output",l,o,"output")):Array.isArray(o.output)&&e.push(...ve("tool_output",l,o,"output",s)):o.type==="function_call"?(o.arguments&&e.push(gn("history",l,String(o.arguments))),o.name&&n.push({name:o.name,args:ri(o.arguments),turn:l})):o.role==="system"||o.role==="developer"?e.push(...ve("system",-1,o,"content",s)):o.role==="user"?e.push(...si(ve(l>=t?"prompt":"history",l,o,"content",s))):o.role==="assistant"&&e.push(...ve("history",l,o,"content",s)))})}return{protocol:"openai-responses",model:String(a.model??""),stream:a.stream===!0,temperature:typeof a.temperature=="number"?a.temperature:void 0,maxOutputTokens:a.max_output_tokens,refs:e,turns:i,toolCalls:n}}function Ds(a){let e=Array.isArray(a.messages)?a.messages:[],n=oi(e,t=>t?.role==="assistant")+1,i=[...li(a.tools)];i.push(...ve("system",-1,a,"system",["text"]));let r=[];return e.forEach((t,s)=>{if(!(!t||typeof t!="object")){if(t.role==="assistant"){i.push(...ve("history",s,t,"content",["text"]));for(let o of Array.isArray(t.content)?t.content:[])o?.type==="tool_use"&&(i.push(gn("history",s,JSON.stringify(o.input??{}))),r.push({name:o.name,args:ri(o.input),turn:s}));return}i.push(...si(ve(s>=n?"prompt":"history",s,t,"content",["text"])));for(let o of Array.isArray(t.content)?t.content:[])o?.type==="tool_result"&&i.push(...ve("tool_output",s,o,"content",["text"]))}}),{protocol:"anthropic",model:String(a.model??""),stream:a.stream===!0,temperature:typeof a.temperature=="number"?a.temperature:void 0,maxOutputTokens:a.max_tokens,refs:i,turns:e.length,toolCalls:r}}function ci(a,e){return a==="anthropic"?Ds(e):a==="openai-responses"?Os(e):js(e)}function ui(a){return/^\/v1\/chat\/completions\/?$/.test(a)?"openai-chat":/^\/v1\/responses\/?$/.test(a)?"openai-responses":/^\/v1\/messages\/?$/.test(a)?"anthropic":null}function hn(a){let e=Object.fromEntries(pn.map(n=>[n,[]]));for(let n of a){let i=n.get();if(!(typeof i!="string"||!i))if(n.part==="prompt"){let{instruction:r,material:t}=Da(i);e.prompt.push(r),t.trim()&&e.context.push(t)}else e[n.part].push(i)}return e}function Ns(a){if(!a||typeof a!="object")return{};let e={};if(typeof a.prompt_tokens=="number")e.inputTokens=a.prompt_tokens,e.outputTokens=a.completion_tokens,e.cachedInputTokens=a.prompt_tokens_details?.cached_tokens,e.reasoningTokens=a.completion_tokens_details?.reasoning_tokens;else if("cache_read_input_tokens"in a||"cache_creation_input_tokens"in a){let n=a.cache_read_input_tokens??0,i=a.cache_creation_input_tokens??0;typeof a.input_tokens=="number"&&(e.inputTokens=a.input_tokens+n+i),e.outputTokens=a.output_tokens,e.cachedInputTokens=n,e.cacheWriteTokens=i}else e.inputTokens=a.input_tokens,e.outputTokens=a.output_tokens,e.cachedInputTokens=a.input_tokens_details?.cached_tokens,e.reasoningTokens=a.output_tokens_details?.reasoning_tokens;for(let n of Object.keys(e))typeof e[n]!="number"&&delete e[n];return e}function Mt(a,e){let n={...a};for(let[i,r]of Object.entries(e))n[i]=Math.max(n[i]??0,r);return n}function la(a){return Ns(a?.usage??a?.message?.usage??a?.response?.usage)}function di(a,e,n){return a==="anthropic"?{type:"error",error:{type:e===401?"authentication_error":"invalid_request_error",message:n}}:{error:{message:n,type:e===401?"authentication_error":"invalid_request_error",code:null}}}var bn=class{factors=new Map;factor(e){return e.tokenizer==="heuristic"?this.factors.get(e.id)?.factor??1:1}raw(e,n){return Ce(e,n).tokens}count(e,n){return Math.round(this.raw(e,n)*this.factor(n))}observe(e,n,i){if(e.tokenizer!=="heuristic"||n<50||!(i>0))return;let r=Math.min(3,Math.max(1/3,i/n)),t=this.factors.get(e.id),s=(t?.samples??0)+1,o=Math.max(1/s,.1);this.factors.set(e.id,{factor:t?t.factor+(r-t.factor)*o:r,samples:s})}snapshot(){return Object.fromEntries([...this.factors].map(([e,n])=>[e,{factor:Math.round(n.factor*1e3)/1e3,samples:n.samples}]))}};function fn(a,e,n){let i=hn(a),r=Object.fromEntries(pn.map(o=>[o,0])),t=0;for(let o of pn)for(let l of i[o]){let c=n.raw(l,e);t+=c,r[o]+=Math.round(c*n.factor(e))}let s=a.filter(o=>o.part==="tool_output").map(o=>n.count(o.get()??"",e));return{parts:r,total:Object.values(r).reduce((o,l)=>o+l,0),raw:t,toolOutputs:s}}function Bs(a){let e=a.trim();if(!/^[[{]/.test(e)||!e.includes(`
3284
- `))return null;try{let n=JSON.stringify(JSON.parse(e));return n.length<a.length?n:null}catch{return null}}function Fs(a,e=3){let n=a.split(`
3285
+ `);return r!==a&&e.push("whitespace in code"),r}function ea(a,e){let n=[],{instruction:i}=Va(a),r=i.length,t=e.task==="debugging"&&e.level!=="light",s=0,o=[];for(let[g,h]of a.split(Ks).entries()){let y=s;if(s+=h.length,g%2===1){o.push(t&&Xt(h)?Yt(h,e.level,n):e.level==="light"?h:ao(h,n));continue}let I=h.slice(0,Math.max(0,r-y)),E=h.slice(I.length),H=E;t&&Xt(E)?H=Yt(E,e.level,n):$t.has(e.task)&&(H=Jt(E,e,n)),o.push(Jt(I,e,n)+H)}let l=o.join(""),c=Me(a,e.profile).tokens,u=Me(l,e.profile).tokens;return u>=c||!l.trim()?{text:a,rules:[],originalTokens:c,tokens:c,saved:0}:{text:l,rules:[...new Set(n)],originalTokens:c,tokens:u,saved:c-u}}function no(a,e="input"){let n=a.pricing;return n?(e==="output"?n.outputPerMTok:e==="cached"?n.cachedInputPerMTok??n.inputPerMTok:n.inputPerMTok)/1e6:null}function ga(a,e,n="input"){let i=no(e,n);return i===null?null:a*i}function Wa(a,e,n="input"){let i=ga(a,e,n);return{tokens:a,usd:i,usdPer1k:i===null?null:i*1e3}}function Zt(a){if(a==null||!Number.isFinite(a))return"n/a";let e=Math.abs(a),n=a<0?"-":"";if(e===0)return"$0";if(e>=100)return`${n}$${e.toLocaleString("en-US",{maximumFractionDigits:0})}`;if(e>=.1)return`${n}$${e.toFixed(2)}`;let i=Math.min(8,Math.max(2,1-Math.floor(Math.log10(e))));return`${n}$${e.toFixed(i).replace(/(\.\d*?[1-9])0+$/,"$1")}`}var Y=a=>a,se={"gpt-astra":Y({id:"gpt-astra",label:"GPT-6 Astra",family:"openai",contextWindow:105e4,tokenizer:"heuristic",charsPerToken:4.2,reasoning:!0,pricing:{inputPerMTok:10,outputPerMTok:50}}),"gpt-reasoning":Y({id:"gpt-reasoning",label:"GPT (thinking)",family:"openai",contextWindow:196e3,tokenizer:"o200k",charsPerToken:4.2,reasoning:!0,lighterAlternative:"the Instant / non-thinking model",pricing:{inputPerMTok:5,outputPerMTok:30,cachedInputPerMTok:.5}}),gpt:Y({id:"gpt",label:"GPT",family:"openai",contextWindow:128e3,tokenizer:"o200k",charsPerToken:4.2,reasoning:!1,pricing:{inputPerMTok:2.5,outputPerMTok:15,cachedInputPerMTok:.25}}),"claude-fable":Y({id:"claude-fable",label:"Claude Fable",family:"anthropic",contextWindow:1e6,tokenizer:"heuristic",charsPerToken:3.5,reasoning:!0,notes:["Claude reads XML-style tags well: wrap pasted material in <doc>\u2026</doc> instead of explaining it."],pricing:{inputPerMTok:10,outputPerMTok:50,cachedInputPerMTok:.25}}),"claude-opus":Y({id:"claude-opus",label:"Claude Opus",family:"anthropic",contextWindow:2e5,tokenizer:"heuristic",charsPerToken:3.5,reasoning:!1,lighterAlternative:"Sonnet or Haiku",notes:["Claude reads XML-style tags well: wrap pasted material in <doc>\u2026</doc> instead of explaining it."],pricing:{inputPerMTok:4,outputPerMTok:20,cachedInputPerMTok:.2}}),"claude-sonnet":Y({id:"claude-sonnet",label:"Claude Sonnet",family:"anthropic",contextWindow:2e5,tokenizer:"heuristic",charsPerToken:3.5,reasoning:!1,lighterAlternative:"Haiku",notes:["Claude reads XML-style tags well: wrap pasted material in <doc>\u2026</doc> instead of explaining it."],pricing:{inputPerMTok:2,outputPerMTok:10,cachedInputPerMTok:.2}}),"claude-haiku":Y({id:"claude-haiku",label:"Claude Haiku",family:"anthropic",contextWindow:2e5,tokenizer:"heuristic",charsPerToken:3.5,reasoning:!1,pricing:{inputPerMTok:.1,outputPerMTok:.5,cachedInputPerMTok:.01}}),"gemini-pro":Y({id:"gemini-pro",label:"Gemini Pro",family:"google",contextWindow:1e6,tokenizer:"heuristic",charsPerToken:4,reasoning:!0,lighterAlternative:"Flash",pricing:{inputPerMTok:2,outputPerMTok:12,cachedInputPerMTok:.2,longContext:{aboveTokens:2e5,inputPerMTok:4,outputPerMTok:18}}}),"gemini-flash":Y({id:"gemini-flash",label:"Gemini Flash",family:"google",contextWindow:1e6,tokenizer:"heuristic",charsPerToken:4,reasoning:!1,pricing:{inputPerMTok:1.5,outputPerMTok:9,cachedInputPerMTok:.15}}),deepseek:Y({id:"deepseek",label:"DeepSeek",family:"deepseek",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!1,pricing:{inputPerMTok:.28,outputPerMTok:.42,cachedInputPerMTok:.028}}),"deepseek-reasoning":Y({id:"deepseek-reasoning",label:"DeepSeek (thinking)",family:"deepseek",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!0,lighterAlternative:"the non-thinking mode",pricing:{inputPerMTok:.55,outputPerMTok:2.19,cachedInputPerMTok:.14}}),mistral:Y({id:"mistral",label:"Mistral",family:"mistral",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!1,pricing:{inputPerMTok:2,outputPerMTok:6}}),grok:Y({id:"grok",label:"Grok",family:"xai",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:4,reasoning:!1,pricing:{inputPerMTok:2,outputPerMTok:6}}),llama:Y({id:"llama",label:"Llama",family:"other",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.9,reasoning:!1,pricing:{inputPerMTok:.27,outputPerMTok:.85}}),qwen:Y({id:"qwen",label:"Qwen",family:"other",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!1,pricing:{inputPerMTok:.4,outputPerMTok:1.2}}),kimi:Y({id:"kimi",label:"Kimi",family:"other",contextWindow:256e3,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!1,pricing:{inputPerMTok:.6,outputPerMTok:2.5,cachedInputPerMTok:.15}}),glm:Y({id:"glm",label:"GLM",family:"other",contextWindow:2e5,tokenizer:"heuristic",charsPerToken:3.8,reasoning:!1,pricing:{inputPerMTok:.6,outputPerMTok:2.2,cachedInputPerMTok:.11}}),command:Y({id:"command",label:"Cohere Command",family:"other",contextWindow:256e3,tokenizer:"heuristic",charsPerToken:4,reasoning:!1,pricing:{inputPerMTok:2.5,outputPerMTok:10}}),sonar:Y({id:"sonar",label:"Perplexity Sonar",family:"other",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:4,reasoning:!1,pricing:{inputPerMTok:1,outputPerMTok:1}}),gemma:Y({id:"gemma",label:"Gemma",family:"other",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:3.9,reasoning:!1,pricing:{inputPerMTok:.1,outputPerMTok:.2}}),phi:Y({id:"phi",label:"Phi",family:"other",contextWindow:16e3,tokenizer:"heuristic",charsPerToken:3.9,reasoning:!1,pricing:{inputPerMTok:.07,outputPerMTok:.14}}),generic:Y({id:"generic",label:"Unknown model",family:"other",contextWindow:128e3,tokenizer:"heuristic",charsPerToken:4,reasoning:!1,pricing:{inputPerMTok:2,outputPerMTok:10}})},io=[[/\b(fable|mythos)\b/,"claude-fable"],[/\bastra\b|\bgpt[- ]?6\b/,"gpt-astra"],[/\bclaude\b.*\bopus\b|\bopus\b/,"claude-opus"],[/\bsonnet\b/,"claude-sonnet"],[/\bhaiku\b/,"claude-haiku"],[/\b(qwen|qwq)/,"qwen"],[/\b(glm|chatglm|zhipu)\b|\bglm-?\d/,"glm"],[/\b(kimi|moonshot)/,"kimi"],[/\bgemma/,"gemma"],[/\bgemini\b.*\bflash\b|\bflash\b/,"gemini-flash"],[/\bgemini\b.*\b(pro|ultra|deep think)\b|^\s*\d(\.\d)?\s*pro\b|\bdeep think\b/,"gemini-pro"],[/\bdeepseek\b.*\b(r1|reason|think|deepthink)|\bdeepthink\b/,"deepseek-reasoning"],[/\bdeepseek\b/,"deepseek"],[/\b(mistral|le chat|magistral|codestral)\b/,"mistral"],[/\bgrok\b/,"grok"],[/\bllama|codellama/,"llama"],[/\bcommand[- ]?(r|a)\b|\bcohere\b/,"command"],[/\bsonar\b|\bperplexity\b/,"sonar"],[/\bphi-?\d/,"phi"],[/\bo[1-9](-mini|-pro)?\b|\bgpt[- ]?\S*\s*(thinking|pro)\b|\bthinking\b/,"gpt-reasoning"],[/\b(gpt|chatgpt)\b|\bgpt-?\d/,"gpt"],[/\bgemini\b/,"gemini-pro"],[/\bclaude\b/,"claude-sonnet"]];var to={chatgpt:"gpt",claude:"claude-sonnet",gemini:"gemini-flash",deepseek:"deepseek",mistral:"mistral",grok:"grok",generic:"generic"},Ka=[],ro=a=>a.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");function so(a){let e=/^\/(.+)\/([a-z]*)$/.exec(a);return e?new RegExp(e[1],e[2].replace(/[gy]/g,"").replace(/^(?!.*i)/,"i")):new RegExp(ro(a.toLowerCase().trim()),"i")}function ki(a){if(!a.id||!(a.contextWindow>0))throw new Error("A custom model needs an id and a positive contextWindow.");let e={id:a.id,label:a.label??a.id,family:a.family??"other",contextWindow:a.contextWindow,tokenizer:a.tokenizer??"heuristic",charsPerToken:a.charsPerToken??4,reasoning:a.reasoning??!1,lighterAlternative:a.lighterAlternative,notes:a.notes,pricing:a.pricing};yi(a.id),se[e.id]=e;for(let n of a.match?.length?a.match:[a.id])Ka.push([so(n),e.id]);return e}function yi(a){for(let e=Ka.length-1;e>=0;e--)Ka[e][1]===a&&Ka.splice(e,1);a in er?se[a]=er[a]:delete se[a]}var er={...se};function Ca(a,e="generic"){let n=(a??"").toLowerCase().replace(/\s+/g," ").trim();if(n){for(let[i,r]of Ka)if(i.test(n))return se[r];if(e==="gemini"&&/\b(pro|deep think)\b/.test(n))return se["gemini-pro"];if(e==="gemini"&&/\bflash\b/.test(n))return se["gemini-flash"];if(e==="deepseek"&&/\b(deepthink|r1|think)/.test(n))return se["deepseek-reasoning"];for(let[i,r]of io)if(i.test(n))return se[r]}return se[to[e]??"generic"]}function ar(a){let e=typeof a.model=="string"?Ca(a.model,a.site):a.model,n=a.pricing?{...e,pricing:a.pricing}:e,i=pa(a.prompt),{tokens:r,exact:t}=Me(a.prompt,n),s=Na(a.conversationTokens??0,r,n,a.contextWindow),o=bt(a.level??"auto",s),l=ea(a.prompt,{profile:n,task:i.task,level:o}),c=Da({profile:n,task:i.task,signals:i.signals,promptTokens:r,usage:s,text:a.prompt}),u={pricing:n.pricing,promptUsd:ga(r,n),sendUsd:ga((a.conversationTokens??0)+r,n),saved:Wa(l.saved,n)},g=Object.entries(bi(a.prompt,l.text)).map(([y,[I,E]])=>`${E}/${I} ${y}s`).join(", "),h={text:l.text,tokens:l.tokens,changes:l.saved>0?l.rules.map(y=>`removed ${y}`):[],kept:g||"every instruction"};return{profile:n,task:i,promptTokens:r,exact:t,usage:s,level:o,optimized:l,tips:c,handoffPrompt:kt(i.task),cost:u,best:h}}import{createHash as ho}from"node:crypto";import{createHash as lo}from"node:crypto";var En=a=>lo("sha256").update(a).digest("hex").slice(0,24);function co(a){if(!(a.length<24)){if(a.readUInt32BE(0)===2303741511)return{width:a.readUInt32BE(16),height:a.readUInt32BE(20)};if(a.toString("ascii",0,3)==="GIF")return{width:a.readUInt16LE(6),height:a.readUInt16LE(8)};if(a.toString("ascii",0,4)==="RIFF"&&a.toString("ascii",8,12)==="WEBP"){let e=a.toString("ascii",12,16);if(e==="VP8X"&&a.length>=30)return{width:1+a.readUIntLE(24,3),height:1+a.readUIntLE(27,3)};if(e==="VP8 "&&a.length>=30)return{width:a.readUInt16LE(26)&16383,height:a.readUInt16LE(28)&16383};if(e==="VP8L"&&a.length>=25){let n=a.readUInt32LE(21);return{width:1+(n&16383),height:1+(n>>14&16383)}}return}if(a[0]===255&&a[1]===216){let e=2;for(;e+9<a.length;){if(a[e]!==255)return;let n=a[e+1],i=a.readUInt16BE(e+2);if(n>=192&&n<=207&&![196,200,204].includes(n))return{width:a.readUInt16BE(e+7),height:a.readUInt16BE(e+5)};e+=2+i}}}}function nr(a){let e=/^data:[^;,]*;base64,(.*)$/s.exec(a);return e?Buffer.from(e[1],"base64"):void 0}function An(a,e){let n=[],i=(t,s)=>{t.forEach((o,l)=>{if(!o||typeof o!="object")return;let c,u,g,h=I=>({type:"text",text:I});if(a==="openai-chat"&&o.type==="image_url"){let I=typeof o.image_url=="string"?o.image_url:o.image_url?.url;if(typeof I!="string")return;c=nr(I),u=En(I),g=o.image_url?.detail}else if(a==="openai-responses"&&o.type==="input_image"){if(typeof o.image_url!="string")return;c=nr(o.image_url),u=En(o.image_url),g=o.detail,h=I=>({type:"input_text",text:I})}else if(a==="anthropic"&&o.type==="image"){let I=o.source??{};if(I.type==="base64"&&typeof I.data=="string")c=Buffer.from(I.data,"base64"),u=En(I.data);else if(typeof I.url=="string")u=En(I.url);else return}else return a==="anthropic"&&o.type==="tool_result"&&Array.isArray(o.content)?i(o.content,s):void 0;let y=c?co(c):void 0;n.push({turn:s,key:u,...y,detail:g,replace:I=>t[l]=h(I)})})};return(a==="openai-responses"?Array.isArray(e?.input)?e.input:[]:Array.isArray(e?.messages)?e.messages:[]).forEach((t,s)=>{Array.isArray(t?.content)&&i(t.content,s)}),n}function vi(a,e){if(a==="openai"&&e.detail==="low")return 85;if(!e.width||!e.height)return;let n=e.width,i=e.height;if(a==="anthropic"){let s=Math.min(1,1568/Math.max(n,i),Math.sqrt(115e4/(n*i)));return Math.min(1600,Math.ceil(n*s*i*s/750))}let r=Math.min(1,2048/Math.max(n,i));n*=r,i*=r;let t=Math.min(1,768/Math.min(n,i));return n*=t,i*=t,85+170*Math.ceil(n/512)*Math.ceil(i/512)}function ir(a,e){let n=new Map,i=0,r=0;for(let t of a){let s=n.get(t.key);if(s===void 0){n.set(t.key,t.turn);continue}s!==t.turn&&(t.replace(`[Token Lens: same image as in message ${s} above]`),i+=vi(e,t)??0,r++)}return{saved:i,count:r}}var Tn=["system","tools","history","tool_output","context","prompt"];function wi(a){let e=a;if(typeof e=="string")try{e=JSON.parse(e)}catch{return e}let n=i=>Array.isArray(i)?i.map(n):i&&typeof i=="object"?Object.fromEntries(Object.keys(i).sort().map(r=>[r,n(i[r])])):i;return JSON.stringify(n(e??{}))}var $a=(a,e,n,i)=>({part:a,turn:e,get:()=>n[i],set:r=>{n[i]=r}}),Cn=(a,e,n)=>({part:a,turn:e,get:()=>n});function Ee(a,e,n,i,r){let t=n[i];return typeof t=="string"?[$a(a,e,n,i)]:Array.isArray(t)?t.filter(s=>s&&typeof s=="object"&&r.includes(s.type)&&typeof s.text=="string").map(s=>$a(a,e,s,"text")):[]}var Si=a=>a.map(e=>({...e,user:!0}));function _i(a,e){for(let n=a.length-1;n>=0;n--)if(e(a[n]))return n;return-1}var Ei=a=>Array.isArray(a)&&a.length?[Cn("tools",-1,JSON.stringify(a))]:[];function uo(a){let e=Array.isArray(a.messages)?a.messages:[],n=_i(e,t=>t?.role==="assistant")+1,i=[...Ei(a.tools??a.functions)],r=[];return e.forEach((t,s)=>{if(!t||typeof t!="object")return;let o=["text"];if(t.role==="system"||t.role==="developer")i.push(...Ee("system",-1,t,"content",o));else if(t.role==="tool"||t.role==="function")i.push(...Ee("tool_output",s,t,"content",o));else if(t.role==="user")i.push(...Si(Ee(s>=n?"prompt":"history",s,t,"content",o)));else if(t.role==="assistant"){i.push(...Ee("history",s,t,"content",o));for(let l of t.tool_calls??[])l?.function?.arguments&&i.push(Cn("history",s,String(l.function.arguments))),l?.function?.name&&r.push({name:l.function.name,args:wi(l.function.arguments),turn:s})}}),{protocol:"openai-chat",model:String(a.model??""),stream:a.stream===!0,temperature:typeof a.temperature=="number"?a.temperature:void 0,maxOutputTokens:a.max_completion_tokens??a.max_tokens,refs:i,turns:e.length,toolCalls:r}}function mo(a){let e=[...Ei(a.tools)];typeof a.instructions=="string"&&e.push($a("system",-1,a,"instructions"));let n=[],i=1;if(typeof a.input=="string")e.push({...$a("prompt",0,a,"input"),user:!0});else if(Array.isArray(a.input)){let r=a.input;i=r.length;let t=_i(r,o=>o?.role==="assistant"||o?.type==="function_call"||o?.type==="reasoning")+1,s=["input_text","output_text","text"];r.forEach((o,l)=>{!o||typeof o!="object"||(o.type==="function_call_output"?typeof o.output=="string"?e.push($a("tool_output",l,o,"output")):Array.isArray(o.output)&&e.push(...Ee("tool_output",l,o,"output",s)):o.type==="function_call"?(o.arguments&&e.push(Cn("history",l,String(o.arguments))),o.name&&n.push({name:o.name,args:wi(o.arguments),turn:l})):o.role==="system"||o.role==="developer"?e.push(...Ee("system",-1,o,"content",s)):o.role==="user"?e.push(...Si(Ee(l>=t?"prompt":"history",l,o,"content",s))):o.role==="assistant"&&e.push(...Ee("history",l,o,"content",s)))})}return{protocol:"openai-responses",model:String(a.model??""),stream:a.stream===!0,temperature:typeof a.temperature=="number"?a.temperature:void 0,maxOutputTokens:a.max_output_tokens,refs:e,turns:i,toolCalls:n}}function po(a){let e=Array.isArray(a.messages)?a.messages:[],n=_i(e,t=>t?.role==="assistant")+1,i=[...Ei(a.tools)];i.push(...Ee("system",-1,a,"system",["text"]));let r=[];return e.forEach((t,s)=>{if(!(!t||typeof t!="object")){if(t.role==="assistant"){i.push(...Ee("history",s,t,"content",["text"]));for(let o of Array.isArray(t.content)?t.content:[])o?.type==="tool_use"&&(i.push(Cn("history",s,JSON.stringify(o.input??{}))),r.push({name:o.name,args:wi(o.input),turn:s}));return}i.push(...Si(Ee(s>=n?"prompt":"history",s,t,"content",["text"])));for(let o of Array.isArray(t.content)?t.content:[])o?.type==="tool_result"&&i.push(...Ee("tool_output",s,o,"content",["text"]))}}),{protocol:"anthropic",model:String(a.model??""),stream:a.stream===!0,temperature:typeof a.temperature=="number"?a.temperature:void 0,maxOutputTokens:a.max_tokens,refs:i,turns:e.length,toolCalls:r}}function Ai(a,e){return a==="anthropic"?po(e):a==="openai-responses"?mo(e):uo(e)}function Ti(a){return/^\/v1\/chat\/completions\/?$/.test(a)?"openai-chat":/^\/v1\/responses\/?$/.test(a)?"openai-responses":/^\/v1\/messages\/?$/.test(a)?"anthropic":null}function Rn(a){let e=Object.fromEntries(Tn.map(n=>[n,[]]));for(let n of a){let i=n.get();if(!(typeof i!="string"||!i))if(n.part==="prompt"){let{instruction:r,material:t}=Va(i);e.prompt.push(r),t.trim()&&e.context.push(t)}else e[n.part].push(i)}return e}function go(a){if(!a||typeof a!="object")return{};let e={};if(typeof a.prompt_tokens=="number")e.inputTokens=a.prompt_tokens,e.outputTokens=a.completion_tokens,e.cachedInputTokens=a.prompt_tokens_details?.cached_tokens,e.reasoningTokens=a.completion_tokens_details?.reasoning_tokens;else if("cache_read_input_tokens"in a||"cache_creation_input_tokens"in a){let n=a.cache_read_input_tokens??0,i=a.cache_creation_input_tokens??0;typeof a.input_tokens=="number"&&(e.inputTokens=a.input_tokens+n+i),e.outputTokens=a.output_tokens,e.cachedInputTokens=n,e.cacheWriteTokens=i}else e.inputTokens=a.input_tokens,e.outputTokens=a.output_tokens,e.cachedInputTokens=a.input_tokens_details?.cached_tokens,e.reasoningTokens=a.output_tokens_details?.reasoning_tokens;for(let n of Object.keys(e))typeof e[n]!="number"&&delete e[n];return e}function tr(a,e){let n={...a};for(let[i,r]of Object.entries(e))n[i]=Math.max(n[i]??0,r);return n}function ha(a){return go(a?.usage??a?.message?.usage??a?.response?.usage)}function Pn(a,e,n){return a==="anthropic"?{type:"error",error:{type:e===401?"authentication_error":"invalid_request_error",message:n}}:{error:{message:n,type:e===401?"authentication_error":"invalid_request_error",code:null}}}var zn=class{factors=new Map;factor(e){return e.tokenizer==="heuristic"?this.factors.get(e.id)?.factor??1:1}raw(e,n){return Me(e,n).tokens}count(e,n){return Math.round(this.raw(e,n)*this.factor(n))}observe(e,n,i){if(e.tokenizer!=="heuristic"||n<50||!(i>0))return;let r=Math.min(3,Math.max(1/3,i/n)),t=this.factors.get(e.id),s=(t?.samples??0)+1,o=Math.max(1/s,.1);this.factors.set(e.id,{factor:t?t.factor+(r-t.factor)*o:r,samples:s})}snapshot(){return Object.fromEntries([...this.factors].map(([e,n])=>[e,{factor:Math.round(n.factor*1e3)/1e3,samples:n.samples}]))}};function In(a,e,n){let i=Rn(a),r=Object.fromEntries(Tn.map(o=>[o,0])),t=0;for(let o of Tn)for(let l of i[o]){let c=n.raw(l,e);t+=c,r[o]+=Math.round(c*n.factor(e))}let s=a.filter(o=>o.part==="tool_output").map(o=>n.count(o.get()??"",e));return{parts:r,total:Object.values(r).reduce((o,l)=>o+l,0),raw:t,toolOutputs:s}}function fo(a){let e=a.trim();if(!/^[[{]/.test(e)||!e.includes(`
3286
+ `))return null;try{let n=JSON.stringify(JSON.parse(e));return n.length<a.length?n:null}catch{return null}}function bo(a,e=3){let n=a.split(`
3285
3287
  `);if(n.length<e)return null;let i=[],r=!1;for(let t=0;t<n.length;){let s=t+1;for(;s<n.length&&n[s]===n[t];)s++;i.push(n[t]),s-t>=e&&n[t].trim()?(i.push(`[previous line repeated ${s-t-1} more times]`),r=!0):i.push(...n.slice(t+1,s)),t=s}return r?i.join(`
3286
- `):null}function Gs(a){let e;try{e=JSON.parse(a)}catch{return null}let n=o=>!!o&&typeof o=="object"&&!Array.isArray(o),i=!1,r=o=>{if(Array.isArray(o)){let l=o.map(r);if(l.length>=5&&l.every(n)){let c=Object.keys(l[0]);if(c.length>0&&l.every(g=>Object.keys(g).length===c.length&&c.every(h=>h in g)))return i=!0,{_columns:c,_rows:l.map(g=>c.map(h=>g[h]))}}return l}return n(o)?Object.fromEntries(Object.entries(o).map(([l,c])=>[l,r(c)])):o},t=r(e);if(!i)return null;let s=JSON.stringify(t);return s.length<=JSON.stringify(e).length*.9?s:null}function qs(a,e){let n;try{n=JSON.parse(a)}catch{return null}let i=(o,l=[],c=0)=>{if(l.length>=200||c>6)return l;if(typeof o=="string"&&o.trim().length>=6)l.push(o.trim().slice(0,24));else if(typeof o=="number"&&String(Math.abs(Math.trunc(o))).length>=4)l.push(String(o));else if(Array.isArray(o))for(let u of o)i(u,l,c+1);else if(o&&typeof o=="object")for(let u of Object.values(o))i(u,l,c+1);return l},r=o=>{let l=[];for(let[c,u]of Object.entries(o)){if(JSON.stringify(u).length<120||c.length>=4&&e.includes(c))continue;let g=i(u);!g.length||g.some(h=>e.includes(h))||(l.push(c),delete o[c])}return l.length&&(o._omitted_by_token_lens=l),l.length},t=o=>!!o&&typeof o=="object"&&!Array.isArray(o),s=0;if(Array.isArray(n))for(let o of n)s+=t(o)?r(o):0;else if(t(n)){for(let o of Object.values(n))if(Array.isArray(o))for(let l of o)s+=t(l)?r(l):0;s+=r(n)}return s?JSON.stringify(n):null}function Us(a,e,n){let i=a.split(/(\n[ \t]*\n)/),r=!1,t=new Set;for(let s=0;s<i.length;s+=2){let o=i[s].trim().replace(/\s+/g," ");if(o.length<200||o.startsWith("[Token Lens:"))continue;let l=n.get(o);t.has(o)?(i[s]="[Token Lens: same passage as earlier in this message]",r=!0):l!==void 0&&l!==e?(i[s]=`[Token Lens: same passage as in message ${l} above]`,r=!0):(l===void 0&&n.set(o,e),t.add(o))}return r?i.join(""):null}function Ye(a,e,n,i,r){let t=0,s=0;for(let o of a){let l=o.get();if(!o.set||typeof l!="string")continue;let c=i(l,o);if(c===null||c===l)continue;let u=h=>h.split(`
3287
- `).length,g=Math.max(e.counter.count(l,e.profile)-e.counter.count(c,e.profile),e.profile.tokenizer==="heuristic"?u(l)-u(c):0);g<=0||c.length>=l.length||(o.set(c),t+=g,s++)}s&&r.push({id:n,saved:t,count:s})}var Fa=a=>!!a&&typeof a=="object"&&(Array.isArray(a)?a.some(Fa):"cache_control"in a||Object.values(a).some(Fa));function Hs(a){if(Fa(a.tools)||Fa(a.system)||Fa(a.messages))return!1;let e={type:"ephemeral"},n=!1;Array.isArray(a.tools)&&a.tools.length&&(a.tools[a.tools.length-1]={...a.tools[a.tools.length-1],cache_control:e},n=!0),typeof a.system=="string"&&a.system?a.system=[{type:"text",text:a.system,cache_control:e}]:Array.isArray(a.system)&&a.system.length&&(a.system[a.system.length-1]={...a.system.at(-1),cache_control:e}),a.system&&(n=!0);let i=Array.isArray(a.messages)?a.messages.at(-1):void 0;if(i&&typeof i.content=="string"&&i.content)i.content=[{type:"text",text:i.content,cache_control:e}],n=!0;else if(i&&Array.isArray(i.content)&&i.content.length){let r=i.content.at(-1);r&&!["thinking","redacted_thinking"].includes(r.type)&&(i.content[i.content.length-1]={...r,cache_control:e},n=!0)}return n}var Vs=1024;function jt(a){let{cfg:e,parsed:n,profile:i,body:r,allow:t}=a,s=[],o=n.refs.filter(S=>S.part==="tool_output");if(e.safe.minifyJson&&Ye(o,a,"minify-json",Bs,s),e.safe.collapseRepeats&&Ye(o,a,"collapse-repeats",S=>Fs(S),s),e.safe.dedupeToolOutputs){let S=new Map,N=(V,O)=>{let L=V.trim();if(L.length<200)return null;let ae=S.get(L);return ae===void 0?(S.set(L,O),null):ae===O?null:`[Token Lens: same output as the earlier tool result in message ${ae}, which is unchanged above]`};Ye(o,a,"dedupe-tool-outputs",(V,O)=>N(V,O.turn),s)}if(e.safe.dedupePassages){let S=new Map,N=n.refs.filter(V=>V.part==="prompt"||V.part==="history"||V.part==="tool_output");Ye(N,a,"dedupe-passages",(V,O)=>Us(V,O.turn,S),s)}if(e.safe.dedupeImages){let S=xt(mn(n.protocol,a.body),a.upstream.type==="anthropic"?"anthropic":"openai");S.count&&s.push({id:"dedupe-images",saved:S.saved,count:S.count})}let l=e.optIn.elideOldToolOutputs||(t.has("elide-tool-outputs")?{keepLast:3,minTokens:300}:!1);if(l){let S=[...new Set(o.map(O=>O.turn))].sort((O,L)=>O-L),N=S.length>l.keepLast?S[S.length-l.keepLast]:-1/0,V=o.filter(O=>O.turn<N);Ye(V,a,"elide-tool-outputs",O=>{let L=a.counter.count(O,i);if(L<l.minTokens)return null;let ae=O.trim().split(`
3288
- `)[0].slice(0,160);return`[Token Lens: earlier tool output omitted, about ${L} tokens. It began: ${ae}]`},s)}(e.optIn.compactJson||t.has("compact-json"))&&Ye(o,a,"compact-json",S=>Gs(S),s);let c=e.optIn.trimToolFields||(t.has("trim-tool-fields")?{keepLast:3}:!1);if(c){let S=[...new Set(o.map(O=>O.turn))].sort((O,L)=>O-L),N=S.length>c.keepLast?S[S.length-c.keepLast]:-1/0,V=O=>[...n.refs.filter(L=>L.turn>O&&L.part!=="tool_output").map(L=>L.get()),...n.toolCalls.filter(L=>L.turn>O).map(L=>L.args)].join(`
3289
- `);Ye(o.filter(O=>O.turn<N),a,"trim-tool-fields",(O,L)=>qs(O,V(L.turn)),s)}let u=[],g=a.level==="auto"?"balanced":a.level,h,I=n.refs.filter(S=>S.part==="prompt").map(S=>S.get()).join(`
3288
+ `):null}function ko(a){let e;try{e=JSON.parse(a)}catch{return null}let n=o=>!!o&&typeof o=="object"&&!Array.isArray(o),i=!1,r=o=>{if(Array.isArray(o)){let l=o.map(r);if(l.length>=5&&l.every(n)){let c=Object.keys(l[0]);if(c.length>0&&l.every(g=>Object.keys(g).length===c.length&&c.every(h=>h in g)))return i=!0,{_columns:c,_rows:l.map(g=>c.map(h=>g[h]))}}return l}return n(o)?Object.fromEntries(Object.entries(o).map(([l,c])=>[l,r(c)])):o},t=r(e);if(!i)return null;let s=JSON.stringify(t);return s.length<=JSON.stringify(e).length*.9?s:null}function yo(a,e){let n;try{n=JSON.parse(a)}catch{return null}let i=(o,l=[],c=0)=>{if(l.length>=200||c>6)return l;if(typeof o=="string"&&o.trim().length>=6)l.push(o.trim().slice(0,24));else if(typeof o=="number"&&String(Math.abs(Math.trunc(o))).length>=4)l.push(String(o));else if(Array.isArray(o))for(let u of o)i(u,l,c+1);else if(o&&typeof o=="object")for(let u of Object.values(o))i(u,l,c+1);return l},r=o=>{let l=[];for(let[c,u]of Object.entries(o)){if(JSON.stringify(u).length<120||c.length>=4&&e.includes(c))continue;let g=i(u);!g.length||g.some(h=>e.includes(h))||(l.push(c),delete o[c])}return l.length&&(o._omitted_by_token_lens=l),l.length},t=o=>!!o&&typeof o=="object"&&!Array.isArray(o),s=0;if(Array.isArray(n))for(let o of n)s+=t(o)?r(o):0;else if(t(n)){for(let o of Object.values(n))if(Array.isArray(o))for(let l of o)s+=t(l)?r(l):0;s+=r(n)}return s?JSON.stringify(n):null}function vo(a,e,n){let i=a.split(/(\n[ \t]*\n)/),r=!1,t=new Set;for(let s=0;s<i.length;s+=2){let o=i[s].trim().replace(/\s+/g," ");if(o.length<200||o.startsWith("[Token Lens:"))continue;let l=n.get(o);t.has(o)?(i[s]="[Token Lens: same passage as earlier in this message]",r=!0):l!==void 0&&l!==e?(i[s]=`[Token Lens: same passage as in message ${l} above]`,r=!0):(l===void 0&&n.set(o,e),t.add(o))}return r?i.join(""):null}function aa(a,e,n,i,r){let t=0,s=0;for(let o of a){let l=o.get();if(!o.set||typeof l!="string")continue;let c=i(l,o);if(c===null||c===l)continue;let u=h=>h.split(`
3289
+ `).length,g=Math.max(e.counter.count(l,e.profile)-e.counter.count(c,e.profile),e.profile.tokenizer==="heuristic"?u(l)-u(c):0);g<=0||c.length>=l.length||(o.set(c),t+=g,s++)}s&&r.push({id:n,saved:t,count:s})}var Ja=a=>!!a&&typeof a=="object"&&(Array.isArray(a)?a.some(Ja):"cache_control"in a||Object.values(a).some(Ja));function wo(a){if(Ja(a.tools)||Ja(a.system)||Ja(a.messages))return!1;let e={type:"ephemeral"},n=!1;Array.isArray(a.tools)&&a.tools.length&&(a.tools[a.tools.length-1]={...a.tools[a.tools.length-1],cache_control:e},n=!0),typeof a.system=="string"&&a.system?a.system=[{type:"text",text:a.system,cache_control:e}]:Array.isArray(a.system)&&a.system.length&&(a.system[a.system.length-1]={...a.system.at(-1),cache_control:e}),a.system&&(n=!0);let i=Array.isArray(a.messages)?a.messages.at(-1):void 0;if(i&&typeof i.content=="string"&&i.content)i.content=[{type:"text",text:i.content,cache_control:e}],n=!0;else if(i&&Array.isArray(i.content)&&i.content.length){let r=i.content.at(-1);r&&!["thinking","redacted_thinking"].includes(r.type)&&(i.content[i.content.length-1]={...r,cache_control:e},n=!0)}return n}var So=1024;function rr(a){let{cfg:e,parsed:n,profile:i,body:r,allow:t}=a,s=[],o=n.refs.filter(E=>E.part==="tool_output");if(e.safe.minifyJson&&aa(o,a,"minify-json",fo,s),e.safe.collapseRepeats&&aa(o,a,"collapse-repeats",E=>bo(E),s),e.safe.dedupeToolOutputs){let E=new Map,H=(W,L)=>{let F=W.trim();if(F.length<200)return null;let ee=E.get(F);return ee===void 0?(E.set(F,L),null):ee===L?null:`[Token Lens: same output as the earlier tool result in message ${ee}, which is unchanged above]`};aa(o,a,"dedupe-tool-outputs",(W,L)=>H(W,L.turn),s)}if(e.safe.dedupePassages){let E=new Map,H=n.refs.filter(W=>W.part==="prompt"||W.part==="history"||W.part==="tool_output");aa(H,a,"dedupe-passages",(W,L)=>vo(W,L.turn,E),s)}if(e.safe.dedupeImages){let E=ir(An(n.protocol,a.body),a.upstream.type==="anthropic"?"anthropic":"openai");E.count&&s.push({id:"dedupe-images",saved:E.saved,count:E.count})}let l=e.optIn.elideOldToolOutputs||(t.has("elide-tool-outputs")?{keepLast:3,minTokens:300}:!1);if(l){let E=[...new Set(o.map(L=>L.turn))].sort((L,F)=>L-F),H=E.length>l.keepLast?E[E.length-l.keepLast]:-1/0,W=o.filter(L=>L.turn<H);aa(W,a,"elide-tool-outputs",L=>{let F=a.counter.count(L,i);if(F<l.minTokens)return null;let ee=L.trim().split(`
3290
+ `)[0].slice(0,160);return`[Token Lens: earlier tool output omitted, about ${F} tokens. It began: ${ee}]`},s)}(e.optIn.compactJson||t.has("compact-json"))&&aa(o,a,"compact-json",E=>ko(E),s);let c=e.optIn.trimToolFields||(t.has("trim-tool-fields")?{keepLast:3}:!1);if(c){let E=[...new Set(o.map(L=>L.turn))].sort((L,F)=>L-F),H=E.length>c.keepLast?E[E.length-c.keepLast]:-1/0,W=L=>[...n.refs.filter(F=>F.turn>L&&F.part!=="tool_output").map(F=>F.get()),...n.toolCalls.filter(F=>F.turn>L).map(F=>F.args)].join(`
3291
+ `);aa(o.filter(L=>L.turn<H),a,"trim-tool-fields",(L,F)=>yo(L,W(F.turn)),s)}let u=[],g=a.level==="auto"?"balanced":a.level,h,I=n.refs.filter(E=>E.part==="prompt").map(E=>E.get()).join(`
3290
3292
 
3291
- `);if(I.trim()){let S=ra(I),N=a.counter.count(I,i);h=S.task,u=Ca({profile:i,task:S.task,signals:S.signals,promptTokens:N,usage:Ra(a.conversationTokens,N,i),text:I})}return e.safe.prompt&&Ye(n.refs.filter(S=>S.user),a,"prompt",S=>Ke(S,{profile:i,task:ra(S).task,level:g}).text,s),{actions:s,tips:u,level:g,task:h}}function Ot(a,e){let{cfg:n,parsed:i,body:r}=a;if(!n.safe.promptCaching||a.prefixRepeats<1)return null;let t=e.parts;return t.system+t.tools+t.history+t.tool_output<Vs?null:i.protocol==="anthropic"?Hs(r)?{id:"prompt-caching",saved:0}:null:!(a.upstream.type==="anthropic"||(a.upstream.promptCacheKey??/(^|\.)api\.openai\.com$/.test(new URL(a.upstream.baseUrl).hostname)))||r.prompt_cache_key!==void 0?null:(r.prompt_cache_key=`tl-${Ls("sha256").update(a.runId).digest("hex").slice(0,24)}`,{id:"prompt-caching",saved:0})}import{randomBytes as Ws}from"node:crypto";var Ks=a=>a.batch??(a.type==="anthropic"||/(^|\.)api\.openai\.com$/.test(new URL(a.baseUrl).hostname)),$s=["/v1/chat/completions","/v1/responses","/v1/embeddings"],kn=class{constructor(e,n){this.deps=e;this.opts=n}deps;opts;jobs=new Map;queued=new Map;submitted=[];timer;busy=!1;canBatch(e,n,i){return Ks(i)?(i.type==="anthropic"?e!=="anthropic":!$s.includes(n))?`Batching isn't available for ${n}.`:null:`This upstream has no batch option. Send the request without x-token-lens-batch, or set "batch": true on an upstream that supports OpenAI's Batch API.`}add(e,n,i){let{stream:r,...t}=e.body,s={...e,body:t,id:`tlb_${Ws(12).toString("hex")}`,status:"queued",createdAt:Date.now()};this.jobs.set(s.id,s);let o=[e.upstream,e.path,JSON.stringify(i)].join("\0"),l=this.queued.get(o);return l||this.queued.set(o,l={upName:e.upstream,up:n,path:e.path,auth:i,jobs:[]}),l.jobs.push(s),l.jobs.length>=this.opts.maxRequests&&this.flush(),this.schedule(),s}take(e,n){let i=this.jobs.get(e);if(!(!i||i.app!==n))return(i.status==="completed"||i.status==="failed")&&this.jobs.delete(e),i}schedule(){if(this.timer)return;let e=(this.queued.size?this.opts.flushSeconds:this.opts.pollSeconds)*1e3;this.timer=setTimeout(()=>{this.timer=void 0,this.tick().finally(()=>{(this.queued.size||this.submitted.length)&&this.schedule()})},e),this.timer.unref?.()}async tick(){if(!this.busy){this.busy=!0;try{await this.flush(),await this.poll();for(let[e,n]of this.jobs)Date.now()-n.createdAt>864e5&&n.status!=="submitted"&&n.status!=="queued"&&this.jobs.delete(e)}finally{this.busy=!1}}}stop(){this.timer&&clearTimeout(this.timer),this.timer=void 0}async flush(){let e=[...this.queued.values()];this.queued.clear();for(let n of e)try{let i=n.up.type==="anthropic"?await this.submitAnthropic(n):await this.submitOpenAI(n);for(let r of n.jobs)r.status="submitted";this.submitted.push({group:n,batchId:i})}catch(i){this.fail(n.jobs,`Submitting the batch failed: ${i.message}`)}}async poll(){let e=[];for(let n of this.submitted)try{(n.group.up.type==="anthropic"?await this.collectAnthropic(n.group,n.batchId):await this.collectOpenAI(n.group,n.batchId))||e.push(n)}catch(i){this.deps.log(JSON.stringify({ts:new Date().toISOString(),level:"error",batch:n.batchId,error:String(i.message??i)})),e.push(n)}this.submitted=e}async call(e,n,i={}){let r={...this.deps.headers(e.up,e.auth),...i.json!==void 0?{"content-type":"application/json"}:{}},t=await this.deps.fetch(n.startsWith("http")?n:this.deps.url(e.up,n),{method:i.method??(i.json!==void 0||i.body?"POST":"GET"),headers:r,body:i.json!==void 0?JSON.stringify(i.json):i.body}),s=await t.text();if(!t.ok)throw new Error(`${t.status} ${s.slice(0,200)}`);return s}async submitOpenAI(e){let n=e.jobs.map(l=>JSON.stringify({custom_id:l.id,method:"POST",url:e.path,body:l.body})).join(`
3293
+ `);if(I.trim()){let E=pa(I),H=a.counter.count(I,i);h=E.task,u=Da({profile:i,task:E.task,signals:E.signals,promptTokens:H,usage:Na(a.conversationTokens,H,i),text:I})}return e.safe.prompt&&aa(n.refs.filter(E=>E.user),a,"prompt",E=>ea(E,{profile:i,task:pa(E).task,level:g}).text,s),{actions:s,tips:u,level:g,task:h}}function sr(a,e){let{cfg:n,parsed:i,body:r}=a;if(!n.safe.promptCaching||a.prefixRepeats<1)return null;let t=e.parts;return t.system+t.tools+t.history+t.tool_output<So?null:i.protocol==="anthropic"?wo(r)?{id:"prompt-caching",saved:0}:null:!(a.upstream.type==="anthropic"||(a.upstream.promptCacheKey??/(^|\.)api\.openai\.com$/.test(new URL(a.upstream.baseUrl).hostname)))||r.prompt_cache_key!==void 0?null:(r.prompt_cache_key=`tl-${ho("sha256").update(a.runId).digest("hex").slice(0,24)}`,{id:"prompt-caching",saved:0})}import{randomBytes as _o}from"node:crypto";var Eo=a=>a.batch??(a.type==="anthropic"||/(^|\.)api\.openai\.com$/.test(new URL(a.baseUrl).hostname)),Ao=["/v1/chat/completions","/v1/responses","/v1/embeddings"],xn=class{constructor(e,n){this.deps=e;this.opts=n}deps;opts;jobs=new Map;queued=new Map;submitted=[];timer;busy=!1;canBatch(e,n,i){return Eo(i)?(i.type==="anthropic"?e!=="anthropic":!Ao.includes(n))?`Batching isn't available for ${n}.`:null:`This upstream has no batch option. Send the request without x-token-lens-batch, or set "batch": true on an upstream that supports OpenAI's Batch API.`}add(e,n,i){let{stream:r,...t}=e.body,s={...e,body:t,id:`tlb_${_o(12).toString("hex")}`,status:"queued",createdAt:Date.now()};this.jobs.set(s.id,s);let o=[e.upstream,e.path,JSON.stringify(i)].join("\0"),l=this.queued.get(o);return l||this.queued.set(o,l={upName:e.upstream,up:n,path:e.path,auth:i,jobs:[]}),l.jobs.push(s),l.jobs.length>=this.opts.maxRequests&&this.flush(),this.schedule(),s}take(e,n){let i=this.jobs.get(e);if(!(!i||i.app!==n))return(i.status==="completed"||i.status==="failed")&&this.jobs.delete(e),i}schedule(){if(this.timer)return;let e=(this.queued.size?this.opts.flushSeconds:this.opts.pollSeconds)*1e3;this.timer=setTimeout(()=>{this.timer=void 0,this.tick().finally(()=>{(this.queued.size||this.submitted.length)&&this.schedule()})},e),this.timer.unref?.()}async tick(){if(!this.busy){this.busy=!0;try{await this.flush(),await this.poll();for(let[e,n]of this.jobs)Date.now()-n.createdAt>864e5&&n.status!=="submitted"&&n.status!=="queued"&&this.jobs.delete(e)}finally{this.busy=!1}}}stop(){this.timer&&clearTimeout(this.timer),this.timer=void 0}async flush(){let e=[...this.queued.values()];this.queued.clear();for(let n of e)try{let i=n.up.type==="anthropic"?await this.submitAnthropic(n):await this.submitOpenAI(n);for(let r of n.jobs)r.status="submitted";this.submitted.push({group:n,batchId:i})}catch(i){this.fail(n.jobs,`Submitting the batch failed: ${i.message}`)}}async poll(){let e=[];for(let n of this.submitted)try{(n.group.up.type==="anthropic"?await this.collectAnthropic(n.group,n.batchId):await this.collectOpenAI(n.group,n.batchId))||e.push(n)}catch(i){this.deps.log(JSON.stringify({ts:new Date().toISOString(),level:"error",batch:n.batchId,error:String(i.message??i)})),e.push(n)}this.submitted=e}async call(e,n,i={}){let r={...this.deps.headers(e.up,e.auth),...i.json!==void 0?{"content-type":"application/json"}:{}},t=await this.deps.fetch(n.startsWith("http")?n:this.deps.url(e.up,n),{method:i.method??(i.json!==void 0||i.body?"POST":"GET"),headers:r,body:i.json!==void 0?JSON.stringify(i.json):i.body}),s=await t.text();if(!t.ok)throw new Error(`${t.status} ${s.slice(0,200)}`);return s}async submitOpenAI(e){let n=e.jobs.map(l=>JSON.stringify({custom_id:l.id,method:"POST",url:e.path,body:l.body})).join(`
3292
3294
  `),i=new FormData;i.append("purpose","batch"),i.append("file",new Blob([n],{type:"application/jsonl"}),"token-lens-batch.jsonl");let r=this.deps.headers(e.up,e.auth);delete r["content-type"];let t=await this.deps.fetch(this.deps.url(e.up,"/v1/files"),{method:"POST",headers:r,body:i});if(!t.ok)throw new Error(`${t.status} ${(await t.text()).slice(0,200)}`);let s=await t.json();return JSON.parse(await this.call(e,"/v1/batches",{json:{input_file_id:s.id,endpoint:e.path,completion_window:"24h"}})).id}async collectOpenAI(e,n){let i=JSON.parse(await this.call(e,`/v1/batches/${n}`));if(["failed","expired","cancelled"].includes(i.status))return this.fail(e.jobs,`The provider's batch ended as "${i.status}".`),!0;if(i.status!=="completed")return!1;let r=new Map;for(let t of[i.output_file_id,i.error_file_id].filter(Boolean))for(let s of(await this.call(e,`/v1/files/${t}/content`)).split(`
3293
3295
  `))if(s.trim()){let o=JSON.parse(s);r.set(o.custom_id,o)}for(let t of e.jobs){let s=r.get(t.id);s?.response?.status_code>=200&&s.response.status_code<300?this.complete(t,s.response.body):this.fail([t],s?.error?.message??s?.response?.body?.error?.message??"No result for this request.")}return!0}async submitAnthropic(e){return JSON.parse(await this.call(e,"/v1/messages/batches",{json:{requests:e.jobs.map(i=>({custom_id:i.id,params:i.body}))}})).id}async collectAnthropic(e,n){let i=JSON.parse(await this.call(e,`/v1/messages/batches/${n}`));if(i.processing_status!=="ended")return!1;let r=new Map;if(i.results_url){for(let t of(await this.call(e,i.results_url)).split(`
3294
- `))if(t.trim()){let s=JSON.parse(t);r.set(s.custom_id,s.result)}}for(let t of e.jobs){let s=r.get(t.id);s?.type==="succeeded"?this.complete(t,s.message):this.fail([t],s?.error?.error?.message??s?.error?.message??`The request ${s?.type??"has no result"}.`)}return!0}complete(e,n){e.status="completed",e.response=n,e.onDone?.(la(n??{}),!0)}fail(e,n){for(let i of e)i.status="failed",i.error=n,i.onDone?.({},!1)}};var mi=a=>{if(typeof a!="string")return a??{};try{return JSON.parse(a)}catch{return a}};function Ie(a,e){let n={text:"",toolCalls:[]};if(!e||typeof e!="object")return n;if(a==="anthropic")for(let i of e.content??[])i?.type==="text"?n.text+=i.text:i?.type==="tool_use"&&n.toolCalls.push({name:i.name,args:i.input??{}});else if(a==="openai-responses")for(let i of e.output??[]){if(i?.type==="message")for(let r of i.content??[])typeof r?.text=="string"&&(n.text+=r.text);i?.type==="function_call"&&n.toolCalls.push({name:i.name,args:mi(i.arguments)})}else{let i=e.choices?.[0]?.message??{};typeof i.content=="string"&&(n.text=i.content);for(let r of i.tool_calls??[])n.toolCalls.push({name:r?.function?.name,args:mi(r?.function?.arguments)})}return n}var yn=a=>a&&typeof a=="object"?Array.isArray(a)?`[${a.map(yn).join(",")}]`:`{${Object.keys(a).sort().map(e=>`${JSON.stringify(e)}:${yn(a[e])}`).join(",")}}`:JSON.stringify(a),Js=a=>a.toLowerCase().match(/[\p{L}\p{N}]+/gu)??[];function Ys(a,e){if(a.trim()===e.trim())return 1;let n=c=>{let u=Js(c),g=new Map,h=E=>g.set(E,(g.get(E)??0)+1);return u.forEach((E,I)=>{h(E),I&&h(`${u[I-1]} ${E}`)}),g},i=n(a),r=n(e),t=0,s=0;for(let[c,u]of i)t+=Math.min(u,r.get(c)??0);for(let c of i.values())s+=c;for(let c of r.values())s+=c;let o=s?2*t/s:1,l=c=>(c.match(/\d+(?:[.,]\d+)*/g)??[]).sort().join(" ");return l(a)===l(e)?o:Math.min(o,.5)}function vn(a,e,n,i){let r=a.toolCalls.length===e.toolCalls.length&&a.toolCalls.every((s,o)=>s.name===e.toolCalls[o].name&&yn(s.args)===yn(e.toolCalls[o].args)),t=Math.round(Ys(a.text,e.text)*1e3)/1e3;return{at:new Date().toISOString(),sameToolCalls:r,similarity:t,match:r&&t>=i,saved:n}}function Dt(a){let e=a.length;return{checked:e,matched:a.filter(n=>n.match).length,sameToolCalls:a.filter(n=>n.sameToolCalls).length,averageSimilarity:e?Math.round(a.reduce((n,i)=>n+i.similarity,0)/e*1e3)/1e3:0,savedOnChecked:a.reduce((n,i)=>n+i.saved,0)}}function Nt(a,e){let n=[];for(let t of e.split(`
3295
- `))if(t.startsWith("data:"))try{n.push(JSON.parse(t.slice(5)))}catch{}if(a==="openai-responses"){let t=n.find(s=>s?.type==="response.completed")?.response;return t?Ie(a,t):{text:n.filter(s=>s?.type==="response.output_text.delta").map(s=>s.delta??"").join(""),toolCalls:[]}}let i={text:"",toolCalls:[]},r=new Map;if(a==="anthropic"){for(let t of n)if(t?.type==="content_block_start"&&t.content_block?.type==="tool_use")r.set(t.index,{name:t.content_block.name,args:""});else if(t?.type==="content_block_start"&&t.content_block?.type==="text")i.text+=t.content_block.text??"";else if(t?.type==="content_block_delta"&&t.delta?.type==="text_delta")i.text+=t.delta.text??"";else if(t?.type==="content_block_delta"&&t.delta?.type==="input_json_delta"){let s=r.get(t.index);s&&(s.args+=t.delta.partial_json??"")}}else for(let t of n){let s=t?.choices?.[0]?.delta;if(s){typeof s.content=="string"&&(i.text+=s.content);for(let o of s.tool_calls??[]){let l=r.get(o.index??0)??{name:"",args:""};o.function?.name&&(l.name+=o.function.name),o.function?.arguments&&(l.args+=o.function.arguments),r.set(o.index??0,l)}}}for(let[,t]of[...r].sort((s,o)=>s[0]-o[0]))i.toolCalls.push({name:t.name,args:t.args.trim()?mi(t.args):{}});return i}var ca="token_lens_load_tools",pi="Some tools above are listed by name and a short summary only. Before calling any of them, call this tool with the names of the tools you need; you will then get their full definitions.",Lt=(a,e)=>a==="openai-chat"?e?.function?.name:e?.name,Xs=(a,e)=>a==="anthropic"?!e?.type||e.type==="custom":e?.type==="function",gi=a=>{let n=(typeof a=="string"?a.trim():"").split(/(?<=[.!?])\s|\n/)[0]??"";return n.length>120?`${n.slice(0,117)}...`:n},hi={type:"object",properties:{}};function Qs(a,e){return a==="openai-chat"?{type:"function",function:{name:e.function.name,description:gi(e.function.description),parameters:hi}}:a==="openai-responses"?{type:"function",name:e.name,description:gi(e.description),parameters:hi}:{name:e.name,description:gi(e.description),input_schema:hi}}function Zs(a,e){let n={type:"object",properties:{names:{type:"array",items:{type:"string",enum:e},description:"Tools to load."}},required:["names"]};return a==="openai-chat"?{type:"function",function:{name:ca,description:pi,parameters:n}}:a==="openai-responses"?{type:"function",name:ca,description:pi,parameters:n}:{name:ca,description:pi,input_schema:n}}function eo(a,e){let n=e?.tool_choice;if(!(!n||typeof n!="object"))return a==="openai-chat"?n.function?.name:n.name}function Bt(a,e,n){let i=Array.isArray(e?.tools)?e.tools:[];if(e?.stream||e?.tool_choice==="none"||i.length<n)return null;let r=i.filter(t=>Xs(a,t)).map(t=>Lt(a,t)).filter(Boolean);return r.length<n||r.includes(ca)?null:{original:i,lazy:r}}function Ft(a,e,n,i){let r=eo(a,e),t=[];return e.tools=n.original.map(s=>{let o=Lt(a,s);return!o||!n.lazy.includes(o)||i.has(o)||o===r?s:(t.push(o),Qs(a,s))}),t.length?e.tools.push(Zs(a,t)):e.tools=n.original,t}function Gt(a,e,n){let i=new Set;for(let r of Ie(a,e).toolCalls)if(r.name===ca){let t=r.args?.names;for(let s of Array.isArray(t)?t:[])n.includes(s)&&i.add(s);if(!i.size)for(let s of n)i.add(s)}else n.includes(r.name)&&i.add(r.name);return[...i]}function bi(a,e){let n={...a};for(let[i,r]of Object.entries(e))typeof r=="number"&&(n[i]=(n[i]??0)+r);return n}var qt=a=>{if(typeof a!="string")return a??{};try{return JSON.parse(a)}catch{return{}}},Ga=a=>typeof a=="string"?a:Array.isArray(a)?a.map(e=>typeof e=="string"?e:e?.type==="text"?e.text:"").join(""):"";function Ut(a){let e=[],n=Ga(a.system);n&&e.push({role:"system",content:n});for(let s of a.messages??[]){let o=typeof s.content=="string"?[{type:"text",text:s.content}]:Array.isArray(s.content)?s.content:[];if(s.role==="assistant"){let u=o.filter(h=>h.type==="text").map(h=>h.text).join(""),g=o.filter(h=>h.type==="tool_use").map(h=>({id:h.id,type:"function",function:{name:h.name,arguments:JSON.stringify(h.input??{})}}));e.push({role:"assistant",content:u||null,...g.length?{tool_calls:g}:{}});continue}let l=[],c=()=>{l.length&&e.push({role:"user",content:l.every(u=>u.type==="text")?l.map(u=>u.text).join(`
3296
- `):[...l]}),l.length=0};for(let u of o)if(u.type==="tool_result"){c();let g=typeof u.content=="string"?u.content:Ga(u.content);e.push({role:"tool",tool_call_id:u.tool_use_id,content:u.is_error?`Error: ${g}`:g})}else if(u.type==="text")l.push({type:"text",text:u.text});else if(u.type==="image"){let g=u.source??{},h=g.type==="base64"?`data:${g.media_type};base64,${g.data}`:g.url;h&&l.push({type:"image_url",image_url:{url:h}})}c()}let i={model:a.model,messages:e};a.max_tokens!==void 0&&(i.max_tokens=a.max_tokens);for(let s of["temperature","top_p","stream"])a[s]!==void 0&&(i[s]=a[s]);a.stop_sequences&&(i.stop=a.stop_sequences),a.metadata?.user_id&&(i.user=a.metadata.user_id),a.stream&&(i.stream_options={include_usage:!0});let r=(a.tools??[]).filter(s=>!s.type||s.type==="custom");r.length&&(i.tools=r.map(s=>({type:"function",function:{name:s.name,description:s.description,parameters:s.input_schema??{type:"object",properties:{}}}})));let t=a.tool_choice;return t&&r.length&&(t.type==="auto"?i.tool_choice="auto":t.type==="any"?i.tool_choice="required":t.type==="none"?i.tool_choice="none":t.type==="tool"&&(i.tool_choice={type:"function",function:{name:t.name}}),t.disable_parallel_tool_use&&(i.parallel_tool_calls=!1)),i}function Ht(a){let e=[],n=[],i=(l,c)=>{let u=n.at(-1);u?.role===l?u.content.push(...c):n.push({role:l,content:c})};for(let l of a.messages??[])if(l.role==="system"||l.role==="developer")e.push(Ga(l.content));else if(l.role==="tool")i("user",[{type:"tool_result",tool_use_id:l.tool_call_id,content:Ga(l.content)}]);else if(l.role==="assistant"){let c=[],u=Ga(l.content);u&&c.push({type:"text",text:u});for(let g of l.tool_calls??[])c.push({type:"tool_use",id:g.id,name:g.function?.name,input:qt(g.function?.arguments)});c.length&&i("assistant",c)}else{let c=typeof l.content=="string"?[{type:"text",text:l.content}]:Array.isArray(l.content)?l.content:[],u=[];for(let g of c)if(g.type==="text")u.push({type:"text",text:g.text});else if(g.type==="image_url"){let h=typeof g.image_url=="string"?g.image_url:g.image_url?.url,E=/^data:([^;,]+);base64,(.*)$/s.exec(h??"");u.push(E?{type:"image",source:{type:"base64",media_type:E[1],data:E[2]}}:{type:"image",source:{type:"url",url:h}})}u.length&&i("user",u)}let r={model:a.model,max_tokens:a.max_completion_tokens??a.max_tokens??4096,messages:n},t=typeof a.prompt_cache_key=="string";e.length&&(r.system=t?[{type:"text",text:e.join(`
3296
+ `))if(t.trim()){let s=JSON.parse(t);r.set(s.custom_id,s.result)}}for(let t of e.jobs){let s=r.get(t.id);s?.type==="succeeded"?this.complete(t,s.message):this.fail([t],s?.error?.error?.message??s?.error?.message??`The request ${s?.type??"has no result"}.`)}return!0}complete(e,n){e.status="completed",e.response=n,e.onDone?.(ha(n??{}),!0)}fail(e,n){for(let i of e)i.status="failed",i.error=n,i.onDone?.({},!1)}};var Ci=a=>{if(typeof a!="string")return a??{};try{return JSON.parse(a)}catch{return a}};function De(a,e){let n={text:"",toolCalls:[]};if(!e||typeof e!="object")return n;if(a==="anthropic")for(let i of e.content??[])i?.type==="text"?n.text+=i.text:i?.type==="tool_use"&&n.toolCalls.push({name:i.name,args:i.input??{}});else if(a==="openai-responses")for(let i of e.output??[]){if(i?.type==="message")for(let r of i.content??[])typeof r?.text=="string"&&(n.text+=r.text);i?.type==="function_call"&&n.toolCalls.push({name:i.name,args:Ci(i.arguments)})}else{let i=e.choices?.[0]?.message??{};typeof i.content=="string"&&(n.text=i.content);for(let r of i.tool_calls??[])n.toolCalls.push({name:r?.function?.name,args:Ci(r?.function?.arguments)})}return n}var Mn=a=>a&&typeof a=="object"?Array.isArray(a)?`[${a.map(Mn).join(",")}]`:`{${Object.keys(a).sort().map(e=>`${JSON.stringify(e)}:${Mn(a[e])}`).join(",")}}`:JSON.stringify(a),To=a=>a.toLowerCase().match(/[\p{L}\p{N}]+/gu)??[];function Co(a,e){if(a.trim()===e.trim())return 1;let n=c=>{let u=To(c),g=new Map,h=y=>g.set(y,(g.get(y)??0)+1);return u.forEach((y,I)=>{h(y),I&&h(`${u[I-1]} ${y}`)}),g},i=n(a),r=n(e),t=0,s=0;for(let[c,u]of i)t+=Math.min(u,r.get(c)??0);for(let c of i.values())s+=c;for(let c of r.values())s+=c;let o=s?2*t/s:1,l=c=>(c.match(/\d+(?:[.,]\d+)*/g)??[]).sort().join(" ");return l(a)===l(e)?o:Math.min(o,.5)}function jn(a,e,n,i){let r=a.toolCalls.length===e.toolCalls.length&&a.toolCalls.every((s,o)=>s.name===e.toolCalls[o].name&&Mn(s.args)===Mn(e.toolCalls[o].args)),t=Math.round(Co(a.text,e.text)*1e3)/1e3;return{at:new Date().toISOString(),sameToolCalls:r,similarity:t,match:r&&t>=i,saved:n}}function or(a){let e=a.length;return{checked:e,matched:a.filter(n=>n.match).length,sameToolCalls:a.filter(n=>n.sameToolCalls).length,averageSimilarity:e?Math.round(a.reduce((n,i)=>n+i.similarity,0)/e*1e3)/1e3:0,savedOnChecked:a.reduce((n,i)=>n+i.saved,0)}}function lr(a,e){let n=[];for(let t of e.split(`
3297
+ `))if(t.startsWith("data:"))try{n.push(JSON.parse(t.slice(5)))}catch{}if(a==="openai-responses"){let t=n.find(s=>s?.type==="response.completed")?.response;return t?De(a,t):{text:n.filter(s=>s?.type==="response.output_text.delta").map(s=>s.delta??"").join(""),toolCalls:[]}}let i={text:"",toolCalls:[]},r=new Map;if(a==="anthropic"){for(let t of n)if(t?.type==="content_block_start"&&t.content_block?.type==="tool_use")r.set(t.index,{name:t.content_block.name,args:""});else if(t?.type==="content_block_start"&&t.content_block?.type==="text")i.text+=t.content_block.text??"";else if(t?.type==="content_block_delta"&&t.delta?.type==="text_delta")i.text+=t.delta.text??"";else if(t?.type==="content_block_delta"&&t.delta?.type==="input_json_delta"){let s=r.get(t.index);s&&(s.args+=t.delta.partial_json??"")}}else for(let t of n){let s=t?.choices?.[0]?.delta;if(s){typeof s.content=="string"&&(i.text+=s.content);for(let o of s.tool_calls??[]){let l=r.get(o.index??0)??{name:"",args:""};o.function?.name&&(l.name+=o.function.name),o.function?.arguments&&(l.args+=o.function.arguments),r.set(o.index??0,l)}}}for(let[,t]of[...r].sort((s,o)=>s[0]-o[0]))i.toolCalls.push({name:t.name,args:t.args.trim()?Ci(t.args):{}});return i}var fa="token_lens_load_tools",Ri="Some tools above are listed by name and a short summary only. Before calling any of them, call this tool with the names of the tools you need; you will then get their full definitions.",cr=(a,e)=>a==="openai-chat"?e?.function?.name:e?.name,Ro=(a,e)=>a==="anthropic"?!e?.type||e.type==="custom":e?.type==="function",Pi=a=>{let n=(typeof a=="string"?a.trim():"").split(/(?<=[.!?])\s|\n/)[0]??"";return n.length>120?`${n.slice(0,117)}...`:n},zi={type:"object",properties:{}};function Po(a,e){return a==="openai-chat"?{type:"function",function:{name:e.function.name,description:Pi(e.function.description),parameters:zi}}:a==="openai-responses"?{type:"function",name:e.name,description:Pi(e.description),parameters:zi}:{name:e.name,description:Pi(e.description),input_schema:zi}}function zo(a,e){let n={type:"object",properties:{names:{type:"array",items:{type:"string",enum:e},description:"Tools to load."}},required:["names"]};return a==="openai-chat"?{type:"function",function:{name:fa,description:Ri,parameters:n}}:a==="openai-responses"?{type:"function",name:fa,description:Ri,parameters:n}:{name:fa,description:Ri,input_schema:n}}function Io(a,e){let n=e?.tool_choice;if(!(!n||typeof n!="object"))return a==="openai-chat"?n.function?.name:n.name}function ur(a,e,n){let i=Array.isArray(e?.tools)?e.tools:[];if(e?.stream||e?.tool_choice==="none"||i.length<n)return null;let r=i.filter(t=>Ro(a,t)).map(t=>cr(a,t)).filter(Boolean);return r.length<n||r.includes(fa)?null:{original:i,lazy:r}}function dr(a,e,n,i){let r=Io(a,e),t=[];return e.tools=n.original.map(s=>{let o=cr(a,s);return!o||!n.lazy.includes(o)||i.has(o)||o===r?s:(t.push(o),Po(a,s))}),t.length?e.tools.push(zo(a,t)):e.tools=n.original,t}function mr(a,e,n){let i=new Set;for(let r of De(a,e).toolCalls)if(r.name===fa){let t=r.args?.names;for(let s of Array.isArray(t)?t:[])n.includes(s)&&i.add(s);if(!i.size)for(let s of n)i.add(s)}else n.includes(r.name)&&i.add(r.name);return[...i]}function Ii(a,e){let n={...a};for(let[i,r]of Object.entries(e))typeof r=="number"&&(n[i]=(n[i]??0)+r);return n}var pr=a=>{if(typeof a!="string")return a??{};try{return JSON.parse(a)}catch{return{}}},Ya=a=>typeof a=="string"?a:Array.isArray(a)?a.map(e=>typeof e=="string"?e:e?.type==="text"?e.text:"").join(""):"";function gr(a){let e=[],n=Ya(a.system);n&&e.push({role:"system",content:n});for(let s of a.messages??[]){let o=typeof s.content=="string"?[{type:"text",text:s.content}]:Array.isArray(s.content)?s.content:[];if(s.role==="assistant"){let u=o.filter(h=>h.type==="text").map(h=>h.text).join(""),g=o.filter(h=>h.type==="tool_use").map(h=>({id:h.id,type:"function",function:{name:h.name,arguments:JSON.stringify(h.input??{})}}));e.push({role:"assistant",content:u||null,...g.length?{tool_calls:g}:{}});continue}let l=[],c=()=>{l.length&&e.push({role:"user",content:l.every(u=>u.type==="text")?l.map(u=>u.text).join(`
3298
+ `):[...l]}),l.length=0};for(let u of o)if(u.type==="tool_result"){c();let g=typeof u.content=="string"?u.content:Ya(u.content);e.push({role:"tool",tool_call_id:u.tool_use_id,content:u.is_error?`Error: ${g}`:g})}else if(u.type==="text")l.push({type:"text",text:u.text});else if(u.type==="image"){let g=u.source??{},h=g.type==="base64"?`data:${g.media_type};base64,${g.data}`:g.url;h&&l.push({type:"image_url",image_url:{url:h}})}c()}let i={model:a.model,messages:e};a.max_tokens!==void 0&&(i.max_tokens=a.max_tokens);for(let s of["temperature","top_p","stream"])a[s]!==void 0&&(i[s]=a[s]);a.stop_sequences&&(i.stop=a.stop_sequences),a.metadata?.user_id&&(i.user=a.metadata.user_id),a.stream&&(i.stream_options={include_usage:!0});let r=(a.tools??[]).filter(s=>!s.type||s.type==="custom");r.length&&(i.tools=r.map(s=>({type:"function",function:{name:s.name,description:s.description,parameters:s.input_schema??{type:"object",properties:{}}}})));let t=a.tool_choice;return t&&r.length&&(t.type==="auto"?i.tool_choice="auto":t.type==="any"?i.tool_choice="required":t.type==="none"?i.tool_choice="none":t.type==="tool"&&(i.tool_choice={type:"function",function:{name:t.name}}),t.disable_parallel_tool_use&&(i.parallel_tool_calls=!1)),i}function hr(a){let e=[],n=[],i=(l,c)=>{let u=n.at(-1);u?.role===l?u.content.push(...c):n.push({role:l,content:c})};for(let l of a.messages??[])if(l.role==="system"||l.role==="developer")e.push(Ya(l.content));else if(l.role==="tool")i("user",[{type:"tool_result",tool_use_id:l.tool_call_id,content:Ya(l.content)}]);else if(l.role==="assistant"){let c=[],u=Ya(l.content);u&&c.push({type:"text",text:u});for(let g of l.tool_calls??[])c.push({type:"tool_use",id:g.id,name:g.function?.name,input:pr(g.function?.arguments)});c.length&&i("assistant",c)}else{let c=typeof l.content=="string"?[{type:"text",text:l.content}]:Array.isArray(l.content)?l.content:[],u=[];for(let g of c)if(g.type==="text")u.push({type:"text",text:g.text});else if(g.type==="image_url"){let h=typeof g.image_url=="string"?g.image_url:g.image_url?.url,y=/^data:([^;,]+);base64,(.*)$/s.exec(h??"");u.push(y?{type:"image",source:{type:"base64",media_type:y[1],data:y[2]}}:{type:"image",source:{type:"url",url:h}})}u.length&&i("user",u)}let r={model:a.model,max_tokens:a.max_completion_tokens??a.max_tokens??4096,messages:n},t=typeof a.prompt_cache_key=="string";e.length&&(r.system=t?[{type:"text",text:e.join(`
3297
3299
 
3298
3300
  `),cache_control:{type:"ephemeral"}}]:e.join(`
3299
3301
 
3300
- `));for(let l of["temperature","top_p","stream"])a[l]!==void 0&&(r[l]=a[l]);a.stop&&(r.stop_sequences=Array.isArray(a.stop)?a.stop:[a.stop]),a.user&&(r.metadata={user_id:a.user});let s=(a.tools??[]).filter(l=>l.type==="function");s.length&&(r.tools=s.map(l=>({name:l.function.name,description:l.function.description,input_schema:l.function.parameters??{type:"object",properties:{}}})),t&&(r.tools[r.tools.length-1].cache_control={type:"ephemeral"}));let o=a.tool_choice;return o&&s.length&&(o==="auto"?r.tool_choice={type:"auto"}:o==="required"?r.tool_choice={type:"any"}:o==="none"?r.tool_choice={type:"none"}:o.function?.name&&(r.tool_choice={type:"tool",name:o.function.name}),a.parallel_tool_calls===!1&&r.tool_choice&&(r.tool_choice.disable_parallel_tool_use=!0)),r}var Vt={stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",function_call:"tool_use",content_filter:"refusal"},Wt={end_turn:"stop",stop_sequence:"stop",max_tokens:"length",tool_use:"tool_calls",refusal:"content_filter",pause_turn:"stop"};function Kt(a){let e=a.choices?.[0]??{},n=e.message??{},i=[];typeof n.content=="string"&&n.content&&i.push({type:"text",text:n.content});for(let t of n.tool_calls??[])i.push({type:"tool_use",id:t.id,name:t.function?.name,input:qt(t.function?.arguments)});let r=a.usage?.prompt_tokens_details?.cached_tokens??0;return{id:a.id??"msg_token_lens",type:"message",role:"assistant",model:a.model,content:i,stop_reason:Vt[e.finish_reason]??"end_turn",stop_sequence:null,usage:{input_tokens:(a.usage?.prompt_tokens??0)-r,output_tokens:a.usage?.completion_tokens??0,cache_read_input_tokens:r,cache_creation_input_tokens:0}}}function $t(a){let e=(a.content??[]).filter(s=>s.type==="text").map(s=>s.text).join(""),n=(a.content??[]).filter(s=>s.type==="tool_use").map(s=>({id:s.id,type:"function",function:{name:s.name,arguments:JSON.stringify(s.input??{})}})),i=a.usage??{},r=i.cache_read_input_tokens??0,t=(i.input_tokens??0)+r+(i.cache_creation_input_tokens??0);return{id:a.id??"chatcmpl-token-lens",object:"chat.completion",created:Math.floor(Date.now()/1e3),model:a.model,choices:[{index:0,message:{role:"assistant",content:e||null,...n.length?{tool_calls:n}:{}},finish_reason:Wt[a.stop_reason]??"stop"}],usage:{prompt_tokens:t,completion_tokens:i.output_tokens??0,total_tokens:t+(i.output_tokens??0),prompt_tokens_details:{cached_tokens:r}}}}function Jt(a,e,n){let i=e?.error?.message??e?.message??`Upstream error ${n}`;return a==="anthropic-to-openai"?{type:"error",error:{type:n===429?"rate_limit_error":n>=500?"api_error":"invalid_request_error",message:i}}:{error:{message:i,type:e?.error?.type??"upstream_error",code:null}}}var Re=(a,e)=>`${a?`event: ${a}
3302
+ `));for(let l of["temperature","top_p","stream"])a[l]!==void 0&&(r[l]=a[l]);a.stop&&(r.stop_sequences=Array.isArray(a.stop)?a.stop:[a.stop]),a.user&&(r.metadata={user_id:a.user});let s=(a.tools??[]).filter(l=>l.type==="function");s.length&&(r.tools=s.map(l=>({name:l.function.name,description:l.function.description,input_schema:l.function.parameters??{type:"object",properties:{}}})),t&&(r.tools[r.tools.length-1].cache_control={type:"ephemeral"}));let o=a.tool_choice;return o&&s.length&&(o==="auto"?r.tool_choice={type:"auto"}:o==="required"?r.tool_choice={type:"any"}:o==="none"?r.tool_choice={type:"none"}:o.function?.name&&(r.tool_choice={type:"tool",name:o.function.name}),a.parallel_tool_calls===!1&&r.tool_choice&&(r.tool_choice.disable_parallel_tool_use=!0)),r}var fr={stop:"end_turn",length:"max_tokens",tool_calls:"tool_use",function_call:"tool_use",content_filter:"refusal"},br={end_turn:"stop",stop_sequence:"stop",max_tokens:"length",tool_use:"tool_calls",refusal:"content_filter",pause_turn:"stop"};function kr(a){let e=a.choices?.[0]??{},n=e.message??{},i=[];typeof n.content=="string"&&n.content&&i.push({type:"text",text:n.content});for(let t of n.tool_calls??[])i.push({type:"tool_use",id:t.id,name:t.function?.name,input:pr(t.function?.arguments)});let r=a.usage?.prompt_tokens_details?.cached_tokens??0;return{id:a.id??"msg_token_lens",type:"message",role:"assistant",model:a.model,content:i,stop_reason:fr[e.finish_reason]??"end_turn",stop_sequence:null,usage:{input_tokens:(a.usage?.prompt_tokens??0)-r,output_tokens:a.usage?.completion_tokens??0,cache_read_input_tokens:r,cache_creation_input_tokens:0}}}function yr(a){let e=(a.content??[]).filter(s=>s.type==="text").map(s=>s.text).join(""),n=(a.content??[]).filter(s=>s.type==="tool_use").map(s=>({id:s.id,type:"function",function:{name:s.name,arguments:JSON.stringify(s.input??{})}})),i=a.usage??{},r=i.cache_read_input_tokens??0,t=(i.input_tokens??0)+r+(i.cache_creation_input_tokens??0);return{id:a.id??"chatcmpl-token-lens",object:"chat.completion",created:Math.floor(Date.now()/1e3),model:a.model,choices:[{index:0,message:{role:"assistant",content:e||null,...n.length?{tool_calls:n}:{}},finish_reason:br[a.stop_reason]??"stop"}],usage:{prompt_tokens:t,completion_tokens:i.output_tokens??0,total_tokens:t+(i.output_tokens??0),prompt_tokens_details:{cached_tokens:r}}}}function vr(a,e,n){let i=e?.error?.message??e?.message??`Upstream error ${n}`;return a==="anthropic-to-openai"?{type:"error",error:{type:n===429?"rate_limit_error":n>=500?"api_error":"invalid_request_error",message:i}}:{error:{message:i,type:e?.error?.type??"upstream_error",code:null}}}var je=(a,e)=>`${a?`event: ${a}
3301
3303
  `:""}data: ${JSON.stringify(e)}
3302
3304
 
3303
- `,wn=class{constructor(e){this.dir=e}dir;buf="";started=!1;open=null;blocks=0;tools=new Map;stop="end_turn";usage={};model="";id="";calls=0;done=!1;push(e){this.buf+=e;let n=this.buf.split(`
3305
+ `,On=class{constructor(e){this.dir=e}dir;buf="";started=!1;open=null;blocks=0;tools=new Map;stop="end_turn";usage={};model="";id="";calls=0;done=!1;push(e){this.buf+=e;let n=this.buf.split(`
3304
3306
 
3305
3307
  `);return this.buf=n.pop()??"",n.map(i=>this.event(i)).join("")}end(){let e=this.buf.trim()?this.event(this.buf):"";return this.buf="",e+this.finish()}event(e){let n=e.split(`
3306
- `).filter(r=>r.startsWith("data:")).map(r=>r.slice(5).trim()).join("");if(!n||n==="[DONE]")return"";let i;try{i=JSON.parse(n)}catch{return""}return this.dir==="anthropic-to-openai"?this.fromChat(i):this.fromAnthropic(i)}fromChat(e){let n="";this.started||(this.started=!0,this.model=e.model??"",n+=Re("message_start",{type:"message_start",message:{id:e.id??"msg_token_lens",type:"message",role:"assistant",model:this.model,content:[],stop_reason:null,stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}})),e.usage&&(this.usage=e.usage);let i=e.choices?.[0];if(!i)return n;let r=i.delta??{};typeof r.content=="string"&&r.content&&(this.open?.kind!=="text"&&(n+=this.closeBlock(),this.open={index:this.blocks++,kind:"text"},n+=Re("content_block_start",{type:"content_block_start",index:this.open.index,content_block:{type:"text",text:""}})),n+=Re("content_block_delta",{type:"content_block_delta",index:this.open.index,delta:{type:"text_delta",text:r.content}}));for(let t of r.tool_calls??[]){let s=t.index??0;if(!this.tools.has(s)){n+=this.closeBlock();let o=this.blocks++;this.tools.set(s,o),this.open={index:o,kind:"tool"},n+=Re("content_block_start",{type:"content_block_start",index:o,content_block:{type:"tool_use",id:t.id,name:t.function?.name,input:{}}})}t.function?.arguments&&(n+=Re("content_block_delta",{type:"content_block_delta",index:this.tools.get(s),delta:{type:"input_json_delta",partial_json:t.function.arguments}}))}return i.finish_reason&&(this.stop=Vt[i.finish_reason]??"end_turn"),n}closeBlock(){if(!this.open)return"";let e=Re("content_block_stop",{type:"content_block_stop",index:this.open.index});return this.open=null,e}fromAnthropic(e){let n=(i,r=null,t)=>Re(null,{id:this.id,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:this.model,choices:t?[]:[{index:0,delta:i,finish_reason:r}],...t?{usage:t}:{}});switch(e.type){case"message_start":return this.id=e.message?.id??"chatcmpl-token-lens",this.model=e.message?.model??"",this.usage={...e.message?.usage},n({role:"assistant",content:""});case"content_block_start":if(e.content_block?.type==="tool_use"){let i=this.calls++;return this.tools.set(e.index,i),n({tool_calls:[{index:i,id:e.content_block.id,type:"function",function:{name:e.content_block.name,arguments:""}}]})}return"";case"content_block_delta":return e.delta?.type==="text_delta"?n({content:e.delta.text}):e.delta?.type==="input_json_delta"?n({tool_calls:[{index:this.tools.get(e.index)??0,function:{arguments:e.delta.partial_json}}]}):"";case"message_delta":return e.usage&&(this.usage={...this.usage,...e.usage}),e.delta?.stop_reason&&(this.stop=Wt[e.delta.stop_reason]??"stop"),"";default:return""}}finish(){if(this.done)return"";if(this.done=!0,this.dir==="anthropic-to-openai"){if(!this.started)return"";let t=this.usage?.prompt_tokens_details?.cached_tokens??0;return this.closeBlock()+Re("message_delta",{type:"message_delta",delta:{stop_reason:this.stop,stop_sequence:null},usage:{input_tokens:(this.usage?.prompt_tokens??0)-t,cache_read_input_tokens:t,output_tokens:this.usage?.completion_tokens??0}})+Re("message_stop",{type:"message_stop"})}let e=this.usage??{},n=e.cache_read_input_tokens??0,i=(e.input_tokens??0)+n+(e.cache_creation_input_tokens??0),r={id:this.id,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:this.model};return Re(null,{...r,choices:[{index:0,delta:{},finish_reason:this.stop}]})+Re(null,{...r,choices:[],usage:{prompt_tokens:i,completion_tokens:e.output_tokens??0,total_tokens:i+(e.output_tokens??0),prompt_tokens_details:{cached_tokens:n}}})+`data: [DONE]
3308
+ `).filter(r=>r.startsWith("data:")).map(r=>r.slice(5).trim()).join("");if(!n||n==="[DONE]")return"";let i;try{i=JSON.parse(n)}catch{return""}return this.dir==="anthropic-to-openai"?this.fromChat(i):this.fromAnthropic(i)}fromChat(e){let n="";this.started||(this.started=!0,this.model=e.model??"",n+=je("message_start",{type:"message_start",message:{id:e.id??"msg_token_lens",type:"message",role:"assistant",model:this.model,content:[],stop_reason:null,stop_sequence:null,usage:{input_tokens:0,output_tokens:0}}})),e.usage&&(this.usage=e.usage);let i=e.choices?.[0];if(!i)return n;let r=i.delta??{};typeof r.content=="string"&&r.content&&(this.open?.kind!=="text"&&(n+=this.closeBlock(),this.open={index:this.blocks++,kind:"text"},n+=je("content_block_start",{type:"content_block_start",index:this.open.index,content_block:{type:"text",text:""}})),n+=je("content_block_delta",{type:"content_block_delta",index:this.open.index,delta:{type:"text_delta",text:r.content}}));for(let t of r.tool_calls??[]){let s=t.index??0;if(!this.tools.has(s)){n+=this.closeBlock();let o=this.blocks++;this.tools.set(s,o),this.open={index:o,kind:"tool"},n+=je("content_block_start",{type:"content_block_start",index:o,content_block:{type:"tool_use",id:t.id,name:t.function?.name,input:{}}})}t.function?.arguments&&(n+=je("content_block_delta",{type:"content_block_delta",index:this.tools.get(s),delta:{type:"input_json_delta",partial_json:t.function.arguments}}))}return i.finish_reason&&(this.stop=fr[i.finish_reason]??"end_turn"),n}closeBlock(){if(!this.open)return"";let e=je("content_block_stop",{type:"content_block_stop",index:this.open.index});return this.open=null,e}fromAnthropic(e){let n=(i,r=null,t)=>je(null,{id:this.id,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:this.model,choices:t?[]:[{index:0,delta:i,finish_reason:r}],...t?{usage:t}:{}});switch(e.type){case"message_start":return this.id=e.message?.id??"chatcmpl-token-lens",this.model=e.message?.model??"",this.usage={...e.message?.usage},n({role:"assistant",content:""});case"content_block_start":if(e.content_block?.type==="tool_use"){let i=this.calls++;return this.tools.set(e.index,i),n({tool_calls:[{index:i,id:e.content_block.id,type:"function",function:{name:e.content_block.name,arguments:""}}]})}return"";case"content_block_delta":return e.delta?.type==="text_delta"?n({content:e.delta.text}):e.delta?.type==="input_json_delta"?n({tool_calls:[{index:this.tools.get(e.index)??0,function:{arguments:e.delta.partial_json}}]}):"";case"message_delta":return e.usage&&(this.usage={...this.usage,...e.usage}),e.delta?.stop_reason&&(this.stop=br[e.delta.stop_reason]??"stop"),"";default:return""}}finish(){if(this.done)return"";if(this.done=!0,this.dir==="anthropic-to-openai"){if(!this.started)return"";let t=this.usage?.prompt_tokens_details?.cached_tokens??0;return this.closeBlock()+je("message_delta",{type:"message_delta",delta:{stop_reason:this.stop,stop_sequence:null},usage:{input_tokens:(this.usage?.prompt_tokens??0)-t,cache_read_input_tokens:t,output_tokens:this.usage?.completion_tokens??0}})+je("message_stop",{type:"message_stop"})}let e=this.usage??{},n=e.cache_read_input_tokens??0,i=(e.input_tokens??0)+n+(e.cache_creation_input_tokens??0),r={id:this.id,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:this.model};return je(null,{...r,choices:[{index:0,delta:{},finish_reason:this.stop}]})+je(null,{...r,choices:[],usage:{prompt_tokens:i,completion_tokens:e.output_tokens??0,total_tokens:i+(e.output_tokens??0),prompt_tokens_details:{cached_tokens:n}}})+`data: [DONE]
3307
3309
 
3308
- `}};import{createHash as ao}from"node:crypto";var Fe="token_lens_read_output",fi="Read a tool output that was kept outside the conversation (shown above as [Token Lens: tool output <id> ...]). Pass its id and either a query (words to find; matching lines are returned) or an offset (a slice of the text from that character).",ki={type:"object",properties:{id:{type:"string",description:"The output's id."},query:{type:"string",description:"Words to find in it."},offset:{type:"integer",description:"Character offset to read from."}},required:["id"]};function Yt(a){return a==="openai-chat"?{type:"function",function:{name:Fe,description:fi,parameters:ki}}:a==="openai-responses"?{type:"function",name:Fe,description:fi,parameters:ki}:{name:Fe,description:fi,input_schema:ki}}function Xt(a,e,n,i,r){let t=a.refs.filter(c=>c.part==="tool_output"),s=[...new Set(t.map(c=>c.turn))].sort((c,u)=>c-u),o=s.length>e.keepLast?s[s.length-e.keepLast]:1/0,l=[];for(let c of t){if(c.turn>=o||!c.set)continue;let u=c.get();if(u.startsWith("[Token Lens:"))continue;let g=n.count(u,i);if(g<e.minTokens)continue;let h=`out_${ao("sha256").update(u).digest("hex").slice(0,10)}`;r.set(h,u);let E=u.split(`
3310
+ `}};import{createHash as xo}from"node:crypto";var He="token_lens_read_output",xi="Read a tool output that was kept outside the conversation (shown above as [Token Lens: tool output <id> ...]). Pass its id and either a query (words to find; matching lines are returned) or an offset (a slice of the text from that character).",Mi={type:"object",properties:{id:{type:"string",description:"The output's id."},query:{type:"string",description:"Words to find in it."},offset:{type:"integer",description:"Character offset to read from."}},required:["id"]};function wr(a){return a==="openai-chat"?{type:"function",function:{name:He,description:xi,parameters:Mi}}:a==="openai-responses"?{type:"function",name:He,description:xi,parameters:Mi}:{name:He,description:xi,input_schema:Mi}}function Sr(a,e,n,i,r){let t=a.refs.filter(c=>c.part==="tool_output"),s=[...new Set(t.map(c=>c.turn))].sort((c,u)=>c-u),o=s.length>e.keepLast?s[s.length-e.keepLast]:1/0,l=[];for(let c of t){if(c.turn>=o||!c.set)continue;let u=c.get();if(u.startsWith("[Token Lens:"))continue;let g=n.count(u,i);if(g<e.minTokens)continue;let h=`out_${xo("sha256").update(u).digest("hex").slice(0,10)}`;r.set(h,u);let y=u.split(`
3309
3311
  `).slice(0,3).join(`
3310
3312
  `).slice(0,300);c.set(`[Token Lens: tool output ${h} kept outside the conversation, about ${g} tokens. It begins:
3311
- ${E}
3312
- To read more, call ${Fe} with {"id": "${h}", "query": "..."} or {"id": "${h}", "offset": 0}.]`),l.push(h)}return l}function Qt(a,e){let n=typeof e?.id=="string"?a.get(e.id):void 0;if(n===void 0)return`No kept output with id ${JSON.stringify(e?.id)}.`;if(typeof e?.query=="string"&&e.query.trim()){let t=e.query.toLowerCase().split(/\W+/).filter(c=>c.length>1),s=n.split(`
3313
+ ${y}
3314
+ To read more, call ${He} with {"id": "${h}", "query": "..."} or {"id": "${h}", "offset": 0}.]`),l.push(h)}return l}function _r(a,e){let n=typeof e?.id=="string"?a.get(e.id):void 0;if(n===void 0)return`No kept output with id ${JSON.stringify(e?.id)}.`;if(typeof e?.query=="string"&&e.query.trim()){let t=e.query.toLowerCase().split(/\W+/).filter(c=>c.length>1),s=n.split(`
3313
3315
  `),o=[],l=0;for(let c=0;c<s.length&&l<6e3;c++){let u=s[c].toLowerCase();if(t.some(g=>u.includes(g))){let g=s.slice(Math.max(0,c-1),c+2).join(`
3314
3316
  `);o.push(`[line ${c+1}] ${g}`),l+=g.length}}return o.length?o.join(`
3315
3317
  ---
3316
3318
  `):`No lines in ${e.id} contain: ${e.query}. It has ${s.length} lines; read a slice with an offset instead.`}let i=Math.max(0,Math.trunc(Number(e?.offset)||0));return`${n.slice(i,i+6e3)}${i+6e3<n.length?`
3317
3319
  [continues at offset ${i+6e3} of ${n.length}]`:`
3318
- [end of output]`}`}function Zt(a,e){let n=i=>{if(typeof i!="string")return i??{};try{return JSON.parse(i)}catch{return{}}};return a==="anthropic"?(e?.content??[]).filter(i=>i?.type==="tool_use").map(i=>({id:i.id,name:i.name,args:i.input??{}})):a==="openai-chat"?(e?.choices?.[0]?.message?.tool_calls??[]).map(i=>({id:i.id,name:i.function?.name,args:n(i.function?.arguments)})):[]}function er(a,e,n,i){if(a==="anthropic")e.messages.push({role:"assistant",content:n.content}),e.messages.push({role:"user",content:[...i].map(([r,t])=>({type:"tool_result",tool_use_id:r,content:t}))});else{e.messages.push(n.choices[0].message);for(let[r,t]of i)e.messages.push({role:"tool",tool_call_id:r,content:t})}}var se=a=>String(a??"").replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[e]),we=a=>Math.round(a).toLocaleString("en-US"),Ge=a=>`${a<0?"\u2212":""}$${Math.abs(a)>=1?Math.abs(a).toFixed(2):Math.abs(a).toFixed(4)}`,va=a=>a==null?"\u2013":`${a}%`;function Sn(a,e,n){if(!e.length)return"";let i=[...n.map(([,t])=>t),"Calls","Tokens before","Tokens after","Saved","Cost before","Cost after","Saved","Output unchanged"],r=e.sort((t,s)=>s.savedUsd-t.savedUsd||s.savedTokens-t.savedTokens).map(t=>`<tr>${n.map(([s])=>`<td>${se(t[s])}</td>`).join("")}<td class=num>${we(t.requests??t.calls)}</td><td class=num>${we(t.tokensBefore)}</td><td class=num>${we(t.tokensAfter)}</td><td class=num><b>${we(t.savedTokens)}</b> <span class=muted>${va(t.savedTokensPct)}</span></td><td class=num>${t.priced===!1?"\u2013":Ge(t.costBeforeUsd)}</td><td class=num>${t.priced===!1?"\u2013":Ge(t.costUsd)}</td><td class=num><b>${t.priced===!1?"\u2013":Ge(t.savedUsd)}</b></td><td class=num>${t.checkLabel??va(t.outputUnchangedPct)}</td></tr>`).join("");return`<h2>${se(a)}</h2><div class=scroll><table><thead><tr>${i.map(t=>`<th>${t}</th>`).join("")}</tr></thead><tbody>${r}</tbody></table></div>`}var qa=a=>({...a,tokensBefore:a.inputTokensBefore+a.outputTokens+a.outputTokensAvoided,tokensAfter:a.inputTokens+a.outputTokens,priced:a.pricedRequests>0,checkLabel:a.checks?`${va(a.outputUnchangedPct)} <span class=muted>of ${we(a.checks)} checked</span>`:"\u2013"});function no(a){let e=a.filter(i=>i.findings?.length).slice(0,10);if(!e.length)return"";let n=i=>{let r=i.estSavedTokensPerRun?`saves about <b>${we(i.estSavedTokensPerRun)} tokens</b>${i.estSavedUsdPerRun?` (<b>${Ge(i.estSavedUsdPerRun)}</b>)`:""} on a run like this`:"saving depends on the answer; check it with output checks on",t=(i.fixes??[]).map(s=>`<li><span class=muted>${se(s.where)}:</span> ${se(s.what)}<pre>${se(s.apply)}</pre></li>`).join("");return`<details><summary><b>${se(i.title)}</b> <span class=muted>\xB7 ${r}</span></summary><p class=muted>${se(i.evidence)}${i.automatic?.length?` Already done: ${se(i.automatic.join("; "))}.`:""}</p><ul>${t}</ul></details>`};return`<h2>What to change next</h2><p class=muted>For each recent run, where its tokens go and the change that cuts them, on the same model. Estimates are input tokens at the model's input price.</p>${e.map(i=>`<h3>${se(i.app)} \xB7 ${se(i.agent)} <span class=muted>\xB7 ${se(i.id)} \xB7 ${we(i.calls)} calls</span></h3>${i.findings.map(n).join("")}`).join("")}`}function io(a){return a.length?`<h2>Switched off to keep answers unchanged</h2>
3320
+ [end of output]`}`}function Er(a,e){let n=i=>{if(typeof i!="string")return i??{};try{return JSON.parse(i)}catch{return{}}};return a==="anthropic"?(e?.content??[]).filter(i=>i?.type==="tool_use").map(i=>({id:i.id,name:i.name,args:i.input??{}})):a==="openai-chat"?(e?.choices?.[0]?.message?.tool_calls??[]).map(i=>({id:i.id,name:i.function?.name,args:n(i.function?.arguments)})):[]}function Ar(a,e,n,i){if(a==="anthropic")e.messages.push({role:"assistant",content:n.content}),e.messages.push({role:"user",content:[...i].map(([r,t])=>({type:"tool_result",tool_use_id:r,content:t}))});else{e.messages.push(n.choices[0].message);for(let[r,t]of i)e.messages.push({role:"tool",tool_call_id:r,content:t})}}var oe=a=>String(a??"").replace(/[&<>"']/g,e=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[e]),Ae=a=>Math.round(a).toLocaleString("en-US"),Ve=a=>`${a<0?"\u2212":""}$${Math.abs(a)>=1?Math.abs(a).toFixed(2):Math.abs(a).toFixed(4)}`,Pa=a=>a==null?"\u2013":`${a}%`;function Xa(a,e,n){if(!e.length)return"";let i=[...n.map(([,t])=>t),"Calls","Tokens before","Tokens after","Saved","Cost before","Cost after","Saved","Output unchanged"],r=e.sort((t,s)=>s.savedUsd-t.savedUsd||s.savedTokens-t.savedTokens).map(t=>`<tr>${n.map(([s])=>`<td>${oe(t[s])}</td>`).join("")}<td class=num>${Ae(t.requests??t.calls)}</td><td class=num>${Ae(t.tokensBefore)}</td><td class=num>${Ae(t.tokensAfter)}</td><td class=num><b>${Ae(t.savedTokens)}</b> <span class=muted>${Pa(t.savedTokensPct)}</span></td><td class=num>${t.priced===!1?"\u2013":Ve(t.costBeforeUsd)}</td><td class=num>${t.priced===!1?"\u2013":Ve(t.costUsd)}</td><td class=num><b>${t.priced===!1?"\u2013":Ve(t.savedUsd)}</b></td><td class=num>${t.checkLabel??Pa(t.outputUnchangedPct)}</td></tr>`).join("");return`<h2>${oe(a)}</h2><div class=scroll><table><thead><tr>${i.map(t=>`<th>${t}</th>`).join("")}</tr></thead><tbody>${r}</tbody></table></div>`}var Ra=a=>({...a,tokensBefore:a.inputTokensBefore+a.outputTokens+a.outputTokensAvoided,tokensAfter:a.inputTokens+a.outputTokens,priced:a.pricedRequests>0,checkLabel:a.checks?`${Pa(a.outputUnchangedPct)} <span class=muted>of ${Ae(a.checks)} checked</span>`:"\u2013"});function Mo(a){let e=a.filter(i=>i.findings?.length).slice(0,10);if(!e.length)return"";let n=i=>{let r=i.estSavedTokensPerRun?`saves about <b>${Ae(i.estSavedTokensPerRun)} tokens</b>${i.estSavedUsdPerRun?` (<b>${Ve(i.estSavedUsdPerRun)}</b>)`:""} on a run like this`:"saving depends on the answer; check it with output checks on",t=(i.fixes??[]).map(s=>`<li><span class=muted>${oe(s.where)}:</span> ${oe(s.what)}<pre>${oe(s.apply)}</pre></li>`).join("");return`<details><summary><b>${oe(i.title)}</b> <span class=muted>\xB7 ${r}</span></summary><p class=muted>${oe(i.evidence)}${i.automatic?.length?` Already done: ${oe(i.automatic.join("; "))}.`:""}</p><ul>${t}</ul></details>`};return`<h2>What to change next</h2><p class=muted>For each recent run, where its tokens go and the change that cuts them, on the same model. Estimates are input tokens at the model's input price.</p>${e.map(i=>`<h3>${oe(i.app)} \xB7 ${oe(i.agent)} <span class=muted>\xB7 ${oe(i.id)} \xB7 ${Ae(i.calls)} calls</span></h3>${i.findings.map(n).join("")}`).join("")}`}function jo(a){return a.length?`<h2>Switched off to keep answers unchanged</h2>
3319
3321
  <div class=muted>An output check found a different answer with these fixes in play (and the model answers the original consistently), so they no longer run for that agent. Turn them back on with <code>POST /token-lens/guard/reset</code> (admin key).</div>
3320
- <div class=scroll><table><tr><th>Team</th><th>Agent</th><th>Fix</th><th>Since</th><th class=num>Tool calls</th><th class=num>Text similarity</th></tr>${a.map(n=>`<tr><td>${se(n.app)}</td><td>${se(n.agent)}</td><td>${se(n.fix)}</td><td>${se(n.since)}</td><td class=num>${n.sameToolCalls?"same":"different"}</td><td class=num>${Number(n.similarity).toFixed(2)}</td></tr>`).join("")}</table></div>`:""}function ar(a,e,n=[]){let i=qa(a.total),r=i.unpricedRequests>0;return`<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1">
3322
+ <div class=scroll><table><tr><th>Team</th><th>Agent</th><th>Fix</th><th>Since</th><th class=num>Tool calls</th><th class=num>Text similarity</th></tr>${a.map(n=>`<tr><td>${oe(n.app)}</td><td>${oe(n.agent)}</td><td>${oe(n.fix)}</td><td>${oe(n.since)}</td><td class=num>${n.sameToolCalls?"same":"different"}</td><td class=num>${Number(n.similarity).toFixed(2)}</td></tr>`).join("")}</table></div>`:""}function Tr(a,e,n=[],i=[]){let r=Ra(a.total),t=r.unpricedRequests>0;return`<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1">
3321
3323
  <title>Token Lens savings</title><style>
3322
3324
  :root{--bg:#fff;--fg:#1a1a1a;--muted:#6b6b6b;--line:#e5e5e5;--card:#f7f7f5;--accent:#0b7a4b}
3323
3325
  @media (prefers-color-scheme:dark){:root{--bg:#141414;--fg:#ececec;--muted:#9a9a9a;--line:#2c2c2c;--card:#1d1d1d;--accent:#4cc38a}}
@@ -3331,35 +3333,36 @@ details{border-bottom:1px solid var(--line);padding:6px 0}summary{cursor:pointer
3331
3333
  pre{background:var(--card);border-radius:6px;padding:6px 8px;margin:4px 0 8px;white-space:pre-wrap;word-break:break-word;font-size:12px}.num{text-align:right;font-variant-numeric:tabular-nums}
3332
3334
  </style></head><body><main>
3333
3335
  <h1>Token Lens savings</h1>
3334
- <div class=muted>Since ${se(a.since)} \xB7 same models, same requests; "before" is what these calls would have cost without Token Lens.</div>
3336
+ <div class=muted>Since ${oe(a.since)} \xB7 same models, same requests; "before" is what these calls would have cost without Token Lens.</div>
3335
3337
  <div class=cards>
3336
- <div class=card><div class=l>Tokens saved</div><div class=v>${we(i.savedTokens)}</div><div class=muted>${va(i.savedTokensPct)} of ${we(i.tokensBefore)}</div></div>
3337
- <div class=card><div class=l>Cost before \u2192 after</div><div class=v>${Ge(i.costBeforeUsd)} \u2192 ${Ge(i.costUsd)}</div><div class=muted>${r?`${we(i.unpricedRequests)} calls on models without pricing are counted in tokens only`:"all calls priced"}</div></div>
3338
- <div class=card><div class=l>Money saved</div><div class=v>${Ge(i.savedUsd)}</div><div class=muted>${va(i.savedUsdPct)}${i.checkCostUsd?` \xB7 output checks cost ${Ge(i.checkCostUsd)}, net ${Ge(i.netSavedUsd)}`:""}</div></div>
3339
- <div class=card><div class=l>Output unchanged</div><div class=v>${i.checks?va(i.outputUnchangedPct):"\u2013"}</div><div class=muted>${i.checks?`${we(i.checksMatched)} of ${we(i.checks)} sampled calls gave the same answer and tool calls as the original request`:"no calls checked yet"}</div></div>
3338
+ <div class=card><div class=l>Tokens saved</div><div class=v>${Ae(r.savedTokens)}</div><div class=muted>${Pa(r.savedTokensPct)} of ${Ae(r.tokensBefore)}</div></div>
3339
+ <div class=card><div class=l>Cost before \u2192 after</div><div class=v>${Ve(r.costBeforeUsd)} \u2192 ${Ve(r.costUsd)}</div><div class=muted>${t?`${Ae(r.unpricedRequests)} calls on models without pricing are counted in tokens only`:"all calls priced"}</div></div>
3340
+ <div class=card><div class=l>Money saved</div><div class=v>${Ve(r.savedUsd)}</div><div class=muted>${Pa(r.savedUsdPct)}${r.checkCostUsd?` \xB7 output checks cost ${Ve(r.checkCostUsd)}, net ${Ve(r.netSavedUsd)}`:""}</div></div>
3341
+ <div class=card><div class=l>Output unchanged</div><div class=v>${r.checks?Pa(r.outputUnchangedPct):"\u2013"}</div><div class=muted>${r.checks?`${Ae(r.checksMatched)} of ${Ae(r.checks)} sampled calls gave the same answer and tool calls as the original request`:"no calls checked yet"}</div></div>
3340
3342
  </div>
3341
- ${Sn("By team",a.byTeam.map(qa),[["app","Team"]])}
3342
- ${Sn("By agent",a.byAgent.map(qa),[["app","Team"],["agent","Agent"]])}
3343
- ${Sn("By model",a.byModel.map(qa),[["model","Model"]])}
3344
- ${Sn("Recent runs",e.map(t=>({...t,priced:t.costBeforeUsd>0,checkLabel:t.outputCheck.checked?`${t.outputCheck.matched} of ${t.outputCheck.checked}`:"\u2013"})),[["app","Team"],["agent","Agent"],["id","Run"],["model","Model"]])}
3345
- ${io(n)}
3346
- ${no(e)}
3347
- <p class=muted>Details per run, with what is growing and what was done about it: <code>/token-lens/runs/&lt;run id&gt;</code>. Machine-readable: <code>/token-lens/report.json</code>. For finance: <a href="report.csv">savings by team, agent and model (CSV)</a> \xB7 <a href="report.csv?by=run">by run (CSV)</a>.</p>
3348
- </main></body></html>`}var to=[["requests","requests"],["tokensBefore","tokens_before"],["tokensAfter","tokens_after"],["savedTokens","saved_tokens"],["savedTokensPct","saved_tokens_pct"],["costBeforeUsd","cost_before_usd"],["costUsd","cost_usd"],["savedUsd","saved_usd"],["checkCostUsd","output_check_cost_usd"],["netSavedUsd","net_saved_usd"],["checks","output_checks"],["outputUnchangedPct","output_unchanged_pct"],["unpricedRequests","unpriced_requests"]],ro=a=>{let e=a==null?"":String(a),n=/^[=+\-@\t\r]/.test(e)&&!/^-?\d/.test(e)?`'${e}`:e;return/[",\n\r]/.test(n)?`"${n.replace(/"/g,'""')}"`:n};function nr(a,e){let i=[...e==="run"?[["id","run"],["app","team"],["agent","agent"],["model","model"],["firstSeen","first_seen"],["lastSeen","last_seen"]]:[["app","team"],["agent","agent"],["model","model"]],...to],r=[i.map(([,t])=>t).join(",")];for(let t of a){let s=e==="run"?{...t,checks:t.outputCheck?.checked,outputUnchangedPct:t.outputCheck?.checked?Math.round(t.outputCheck.matched/t.outputCheck.checked*1e3)/10:null,requests:t.calls}:qa(t);r.push(i.map(([o])=>ro(s[o])).join(","))}return r.join(`\r
3343
+ ${Xa("By team",a.byTeam.map(Ra),[["app","Team"]])}
3344
+ ${Xa("By agent",a.byAgent.map(Ra),[["app","Team"],["agent","Agent"]])}
3345
+ ${Xa("By model",a.byModel.map(Ra),[["model","Model"]])}
3346
+ ${i.length?Xa(`By customer${i.length>50?" (top 50 by cost before)":""}`,i.slice(0,50).map(s=>Ra({...s,app:s.team})),[["app","Team"],["customer","Customer"]]):""}
3347
+ ${Xa("Recent runs",e.map(s=>({...s,priced:s.costBeforeUsd>0,checkLabel:s.outputCheck.checked?`${s.outputCheck.matched} of ${s.outputCheck.checked}`:"\u2013"})),[["app","Team"],["agent","Agent"],["id","Run"],["model","Model"]])}
3348
+ ${jo(n)}
3349
+ ${Mo(e)}
3350
+ <p class=muted>Details per run, with what is growing and what was done about it: <code>/token-lens/runs/&lt;run id&gt;</code>. Machine-readable: <code>/token-lens/report.json</code>. For finance: <a href="report.csv">savings by team, agent and model (CSV)</a> \xB7 <a href="report.csv?by=run">by run (CSV)</a>${i.length?' \xB7 <a href="customers.csv">by customer (CSV)</a>':""}.</p>
3351
+ </main></body></html>`}var Oo=[["requests","requests"],["tokensBefore","tokens_before"],["tokensAfter","tokens_after"],["savedTokens","saved_tokens"],["savedTokensPct","saved_tokens_pct"],["costBeforeUsd","cost_before_usd"],["costUsd","cost_usd"],["savedUsd","saved_usd"],["checkCostUsd","output_check_cost_usd"],["netSavedUsd","net_saved_usd"],["checks","output_checks"],["outputUnchangedPct","output_unchanged_pct"],["unpricedRequests","unpriced_requests"]],Do=a=>{let e=a==null?"":String(a),n=/^[=+\-@\t\r]/.test(e)&&!/^-?\d/.test(e)?`'${e}`:e;return/[",\n\r]/.test(n)?`"${n.replace(/"/g,'""')}"`:n};function Cr(a,e){let i=[...e==="run"?[["id","run"],["app","team"],["agent","agent"],["model","model"],["firstSeen","first_seen"],["lastSeen","last_seen"]]:[["app","team"],["agent","agent"],["model","model"]],...Oo],r=[i.map(([,t])=>t).join(",")];for(let t of a){let s=e==="run"?{...t,checks:t.outputCheck?.checked,outputUnchangedPct:t.outputCheck?.checked?Math.round(t.outputCheck.matched/t.outputCheck.checked*1e3)/10:null,requests:t.calls}:Ra(t);r.push(i.map(([o])=>Do(s[o])).join(","))}return r.join(`\r
3349
3352
  `)+`\r
3350
- `}import{createHash as so}from"node:crypto";var Ua=(...a)=>so("sha256").update(a.join("\0")).digest("hex").slice(0,16),ir=500,_n=class{constructor(e=2e3){this.maxRuns=e}maxRuns;runs=new Map;get(e){return this.runs.get(e)}open(e,n,i,r="-"){let t=this.runs.get(e);if(t)this.runs.delete(e);else{let s=new Date().toISOString();t={id:e,app:n,agent:r,named:i,firstSeen:s,lastSeen:s,calls:[],prefixes:new Map,requestHashes:new Set,checks:[]}}for(this.runs.set(e,t);this.runs.size>this.maxRuns;)this.runs.delete(this.runs.keys().next().value);return t}record(e,n){e.calls.push(n),e.calls.length>ir&&e.calls.splice(0,e.calls.length-ir),e.lastSeen=n.at}list(){return[...this.runs.values()].reverse()}};function oo(a,e){switch(a){case"repeated-prefix":return[...e.cachingOn?[]:[{where:"model server",what:"On a self-hosted model, cache the shared prefix (hosted OpenAI, Anthropic and Gemini models are cached by the gateway or the provider)",apply:"vllm serve <model> --enable-prefix-caching"}],{where:"agent code",what:"Keep the system prompt and tool list byte-identical between calls: no timestamps, ids or reordered tools in them",apply:"const SYSTEM = buildSystemPrompt(); // build once per run, reuse on every call"},...e.bigTools?[{where:"request header",what:"Send unused tools as a one-line summary and load full definitions only when the agent asks for them (opt-in; output checks run on a sample)",apply:"x-token-lens-allow: lazy-tools"}]:[],...e.bigTools?[{where:"agent code",what:"Send only the tools this step can use",apply:"tools: ALL_TOOLS.filter((t) => toolsForStep(step).includes(t.name))"}]:[]];case"growing-history":return[{where:"agent code",what:"Keep the last few turns plus a running summary instead of the full transcript",apply:'messages = [system, { role: "user", content: `Progress so far: ${summary}` }, ...messages.slice(-6)]'},{where:"system prompt",what:"Ask the model to restate only what the next step needs",apply:"When you finish a step, end with one line: STATE: <facts the next step needs>."}];case"tool-outputs":return[{where:"request header",what:"Leave out fields of older tool outputs the agent never referred to (opt-in; answers checked before it applies)",apply:"x-token-lens-allow: trim-tool-fields"},{where:"request header",what:"Replace older tool outputs with a stub (opt-in; answers checked before it applies)",apply:"x-token-lens-allow: elide-tool-outputs"},{where:"gateway config",what:"The same for every app",apply:'{ "optIn": { "elideOldToolOutputs": { "keepLast": 3, "minTokens": 300 } } }'},{where:"agent code",what:"Return only the fields the agent uses from each tool",apply:'return JSON.stringify(pick(result, ["id", "status", "total"])); // not the whole record, no logs'}];case"large-context":return[{where:"agent code",what:"Retrieve fewer, smaller chunks and drop near-duplicates",apply:"const chunks = dedupe(await search(query, { topK: 4, maxTokensPerChunk: 400 }));"},{where:"agent code",what:"Put a document reused across calls before the question, so it is cached",apply:'messages = [system, { role: "user", content: doc }, { role: "user", content: question }]'}];case"retries":return[{where:"gateway config",what:"Answer identical retries from the gateway's copy (temperature-0 calls)",apply:'{ "safe": { "dedupeRetries": true }, "retryWindowSeconds": 600 }'},{where:"agent code",what:"Retry only on rate limits and server errors, with backoff, never on a parse error with the same input",apply:"if (err.status === 429 || err.status >= 500) await sleep(2 ** attempt * 1000); else throw err;"}];case"reasoning-heavy":return[{where:"agent code",what:"Lower reasoning effort on simple steps (routing, extraction, formatting) on the same model, with output checks on",apply:'reasoning_effort: step.simple ? "low" : "high" // Anthropic: thinking: { type: "enabled", budget_tokens: step.simple ? 1024 : 8000 }'}];case"repeated-tool-calls":return[{where:"agent code",what:`Cache tool results for the run${e.repeat?`, so ${e.repeat.name} with the same input runs once`:""}`,apply:"const cache = new Map(); const run = (name, args) => { const k = name + JSON.stringify(args); if (!cache.has(k)) cache.set(k, tools[name](args)); return cache.get(k); };"},{where:"system prompt",what:"Tell the agent results don't change within a run",apply:"Tool results stay valid for this whole task. Do not call a tool again with the same input; use the earlier result."}];case"loop":return[{where:"gateway config",what:"Cap every run so a loop stops instead of spending",apply:`{ "runBudget": { "maxCalls": ${Math.max(10,e.steps*2)}, "maxCostUsd": 1 } }`},{where:"request header",what:"Or cap one agent's runs",apply:`x-token-lens-max-calls: ${Math.max(10,e.steps*2)}`},{where:"agent code",what:"Give the agent a step limit and stop when a call repeats",apply:`if (step >= MAX_STEPS || sameAsLastCall(call)) break;${e.loop?` // stuck on ${e.loop.name}`:""}`}];case"output-heavy":return[{where:"agent code",what:"Cap output on intermediate steps; leave the final answer as is",apply:"max_tokens: step.final ? undefined : 400"},{where:"system prompt",what:"Ask intermediate steps for brief, structured output",apply:'For intermediate steps reply only with JSON: {"next": ..., "facts": [...]}. No explanations.'}];case"images":return[{where:"agent code",what:"Once the model has described or used an image, keep the description in history instead of the image",apply:'messages = messages.map((m, i) => (i < messages.length - 2 && hasImage(m) ? withoutImages(m, "[screenshot: " + m.description + "]") : m));'},{where:"agent code",what:"Crop screenshots to the region the step needs before sending",apply:"const shot = await page.screenshot({ clip: { x, y, width: 800, height: 600 } });"},{where:"agent code",what:"Where fine detail isn't needed, ask for low detail (OpenAI; can change answers, so check with output checks on)",apply:'{ "type": "image_url", "image_url": { "url": dataUrl, "detail": "low" } }'}];case"cache-breaker":return e.breakKind==="reordered tools"||e.breakKind==="changed tools"?[{where:"agent code",what:"Send the tool list in one fixed order, with fixed descriptions",apply:"tools: [...TOOLS].sort((a, b) => a.name.localeCompare(b.name)) // built once, not per call"}]:[{where:"agent code",what:`Move the ${e.breakKind==="changed text"?"part that changes":e.breakKind} out of the ${e.breakWhere??"system prompt"} and into the newest message, so everything before it stays identical`,apply:'system: STATIC_SYSTEM, // no time, ids or per-call values here\nmessages: [...history, { role: "user", content: `${question}\\n\\nCurrent time: ${new Date().toISOString()}` }]'},{where:"system prompt",what:"If the model needs the date, give it at day precision so it changes once a day, not every call",apply:"Today's date is ${new Date().toISOString().slice(0, 10)}."}];case"json-retries":{let n=e.api??"openai-chat";return[{where:"agent code",what:"Ask for the provider's strict structured output on the same model: the reply always parses, so no retry is needed (run with output checks on)",apply:n==="anthropic"?`tools: [{ name: "result", description: "Return the result", input_schema: RESULT_SCHEMA }],
3353
+ `}import{createHash as No}from"node:crypto";var Qa=(...a)=>No("sha256").update(a.join("\0")).digest("hex").slice(0,16),Rr=500,Dn=class{constructor(e=2e3){this.maxRuns=e}maxRuns;runs=new Map;get(e){return this.runs.get(e)}open(e,n,i,r="-"){let t=this.runs.get(e);if(t)this.runs.delete(e);else{let s=new Date().toISOString();t={id:e,app:n,agent:r,named:i,firstSeen:s,lastSeen:s,calls:[],prefixes:new Map,requestHashes:new Set,checks:[]}}for(this.runs.set(e,t);this.runs.size>this.maxRuns;)this.runs.delete(this.runs.keys().next().value);return t}record(e,n){e.calls.push(n),e.calls.length>Rr&&e.calls.splice(0,e.calls.length-Rr),e.lastSeen=n.at}list(){return[...this.runs.values()].reverse()}};function Lo(a,e){switch(a){case"repeated-prefix":return[...e.cachingOn?[]:[{where:"model server",what:"On a self-hosted model, cache the shared prefix (hosted OpenAI, Anthropic and Gemini models are cached by the gateway or the provider)",apply:"vllm serve <model> --enable-prefix-caching"}],{where:"agent code",what:"Keep the system prompt and tool list byte-identical between calls: no timestamps, ids or reordered tools in them",apply:"const SYSTEM = buildSystemPrompt(); // build once per run, reuse on every call"},...e.bigTools?[{where:"request header",what:"Send unused tools as a one-line summary and load full definitions only when the agent asks for them (opt-in; output checks run on a sample)",apply:"x-token-lens-allow: lazy-tools"}]:[],...e.bigTools?[{where:"agent code",what:"Send only the tools this step can use",apply:"tools: ALL_TOOLS.filter((t) => toolsForStep(step).includes(t.name))"}]:[]];case"growing-history":return[{where:"agent code",what:"Keep the last few turns plus a running summary instead of the full transcript",apply:'messages = [system, { role: "user", content: `Progress so far: ${summary}` }, ...messages.slice(-6)]'},{where:"system prompt",what:"Ask the model to restate only what the next step needs",apply:"When you finish a step, end with one line: STATE: <facts the next step needs>."}];case"tool-outputs":return[{where:"request header",what:"Leave out fields of older tool outputs the agent never referred to (opt-in; answers checked before it applies)",apply:"x-token-lens-allow: trim-tool-fields"},{where:"request header",what:"Replace older tool outputs with a stub (opt-in; answers checked before it applies)",apply:"x-token-lens-allow: elide-tool-outputs"},{where:"gateway config",what:"The same for every app",apply:'{ "optIn": { "elideOldToolOutputs": { "keepLast": 3, "minTokens": 300 } } }'},{where:"agent code",what:"Return only the fields the agent uses from each tool",apply:'return JSON.stringify(pick(result, ["id", "status", "total"])); // not the whole record, no logs'}];case"large-context":return[{where:"agent code",what:"Retrieve fewer, smaller chunks and drop near-duplicates",apply:"const chunks = dedupe(await search(query, { topK: 4, maxTokensPerChunk: 400 }));"},{where:"agent code",what:"Put a document reused across calls before the question, so it is cached",apply:'messages = [system, { role: "user", content: doc }, { role: "user", content: question }]'}];case"retries":return[{where:"gateway config",what:"Answer identical retries from the gateway's copy (temperature-0 calls)",apply:'{ "safe": { "dedupeRetries": true }, "retryWindowSeconds": 600 }'},{where:"agent code",what:"Retry only on rate limits and server errors, with backoff, never on a parse error with the same input",apply:"if (err.status === 429 || err.status >= 500) await sleep(2 ** attempt * 1000); else throw err;"}];case"reasoning-heavy":return[{where:"agent code",what:"Lower reasoning effort on simple steps (routing, extraction, formatting) on the same model, with output checks on",apply:'reasoning_effort: step.simple ? "low" : "high" // Anthropic: thinking: { type: "enabled", budget_tokens: step.simple ? 1024 : 8000 }'}];case"repeated-tool-calls":return[{where:"agent code",what:`Cache tool results for the run${e.repeat?`, so ${e.repeat.name} with the same input runs once`:""}`,apply:"const cache = new Map(); const run = (name, args) => { const k = name + JSON.stringify(args); if (!cache.has(k)) cache.set(k, tools[name](args)); return cache.get(k); };"},{where:"system prompt",what:"Tell the agent results don't change within a run",apply:"Tool results stay valid for this whole task. Do not call a tool again with the same input; use the earlier result."}];case"loop":return[{where:"gateway config",what:"Cap every run so a loop stops instead of spending",apply:`{ "runBudget": { "maxCalls": ${Math.max(10,e.steps*2)}, "maxCostUsd": 1 } }`},{where:"request header",what:"Or cap one agent's runs",apply:`x-token-lens-max-calls: ${Math.max(10,e.steps*2)}`},{where:"agent code",what:"Give the agent a step limit and stop when a call repeats",apply:`if (step >= MAX_STEPS || sameAsLastCall(call)) break;${e.loop?` // stuck on ${e.loop.name}`:""}`}];case"output-heavy":return[{where:"agent code",what:"Cap output on intermediate steps; leave the final answer as is",apply:"max_tokens: step.final ? undefined : 400"},{where:"system prompt",what:"Ask intermediate steps for brief, structured output",apply:'For intermediate steps reply only with JSON: {"next": ..., "facts": [...]}. No explanations.'}];case"images":return[{where:"agent code",what:"Once the model has described or used an image, keep the description in history instead of the image",apply:'messages = messages.map((m, i) => (i < messages.length - 2 && hasImage(m) ? withoutImages(m, "[screenshot: " + m.description + "]") : m));'},{where:"agent code",what:"Crop screenshots to the region the step needs before sending",apply:"const shot = await page.screenshot({ clip: { x, y, width: 800, height: 600 } });"},{where:"agent code",what:"Where fine detail isn't needed, ask for low detail (OpenAI; can change answers, so check with output checks on)",apply:'{ "type": "image_url", "image_url": { "url": dataUrl, "detail": "low" } }'}];case"cache-breaker":return e.breakKind==="reordered tools"||e.breakKind==="changed tools"?[{where:"agent code",what:"Send the tool list in one fixed order, with fixed descriptions",apply:"tools: [...TOOLS].sort((a, b) => a.name.localeCompare(b.name)) // built once, not per call"}]:[{where:"agent code",what:`Move the ${e.breakKind==="changed text"?"part that changes":e.breakKind} out of the ${e.breakWhere??"system prompt"} and into the newest message, so everything before it stays identical`,apply:'system: STATIC_SYSTEM, // no time, ids or per-call values here\nmessages: [...history, { role: "user", content: `${question}\\n\\nCurrent time: ${new Date().toISOString()}` }]'},{where:"system prompt",what:"If the model needs the date, give it at day precision so it changes once a day, not every call",apply:"Today's date is ${new Date().toISOString().slice(0, 10)}."}];case"json-retries":{let n=e.api??"openai-chat";return[{where:"agent code",what:"Ask for the provider's strict structured output on the same model: the reply always parses, so no retry is needed (run with output checks on)",apply:n==="anthropic"?`tools: [{ name: "result", description: "Return the result", input_schema: RESULT_SCHEMA }],
3351
3354
  tool_choice: { type: "tool", name: "result" } // read the answer from the tool_use block's input`:n==="openai-responses"?'text: { format: { type: "json_schema", name: "result", strict: true, schema: RESULT_SCHEMA } }':'response_format: { type: "json_schema", json_schema: { name: "result", strict: true, schema: RESULT_SCHEMA } }'},{where:"agent code",what:"If a reply still doesn't parse, repair it locally before asking the model again",apply:"const data = JSON.parse(jsonrepair(text)); // npm i jsonrepair; only re-ask if this throws"}]}case"shared-reads":return[{where:"agent code",what:"Read shared files once in the orchestrator and pass them to every sub-agent",apply:`const docs = await Promise.all(paths.map(readOnce));
3352
- await Promise.all(subAgents.map((a) => a.run({ task, context: docs })));`},{where:"agent code",what:"Or share one read cache between sub-agents",apply:'const cache = new Map(); const readOnce = (p) => cache.get(p) ?? (cache.set(p, fs.promises.readFile(p, "utf8")), cache.get(p));'},{where:"agent code",what:"Put the shared files in the same place at the top of each sub-agent's prompt, so the provider's cache serves them after the first",apply:'system: [STATIC_SYSTEM, ...docs.map((d) => `<doc path="${d.path}">${d.text}</doc>`)].join("\\n")'}];case"price-tier":return[{where:"agent code",what:`Keep each request under ${H(e.tierAbove??2e5)} input tokens: hand off to a fresh call with a summary first`,apply:`if (estimateTokens(messages) > ${Math.round((e.tierAbove??2e5)*.9)}) messages = [system, { role: "user", content: await summarize(messages) }];`},{where:"request header",what:"Replace older tool outputs with a stub (opt-in; answers checked before it applies)",apply:"x-token-lens-allow: elide-tool-outputs"},{where:"agent code",what:"Retrieve fewer, smaller chunks",apply:"const chunks = await search(query, { topK: 4, maxTokensPerChunk: 400 });"}];case"near-context-limit":return[{where:"agent code",what:"Hand off to a fresh run with a summary before the window fills",apply:'if (usage.input_tokens > 0.7 * CONTEXT_WINDOW) messages = [system, { role: "user", content: await summarize(messages) }];'}];default:return[]}}var H=a=>Math.round(a).toLocaleString("en-US"),ua=(a,e)=>`${e?Math.round(a/e*100):0}%`,Z=a=>a.reduce((e,n)=>e+n,0),tr=a=>a.length>60?a.slice(0,57)+"...":a;function lo(a){let e=new Map;for(let n of a)for(let i of n.actions){let r=e.get(i.id)??{saved:0,calls:0};r.saved+=i.saved,r.calls++,e.set(i.id,r)}return e}var co=a=>`Send the header "x-token-lens-allow: ${a}" on this app's requests, or enable it for everyone in the gateway config.`;function An(a){let e=a.calls.filter(y=>!y.replayed&&y.status<400),n=[];if(!e.length)return[];let i=e.length,r=e[0],t=e[i-1],s=t.input||1,o=y=>i>1?(t.parts[y]-r.parts[y])/(i-1):0,l=lo(a.calls),c=(y,x)=>{let K=l.get(y);return K?[`${x} (${K.calls} of ${a.calls.length} calls${K.saved?`, ${H(K.saved)} tokens saved so far`:""})`]:[]},u=Z(e.map(y=>y.usage.cachedInputTokens??0)),g=u?[`provider reports ${H(u)} input tokens served from cache`]:[],h=t.parts.system+t.parts.tools;i>1&&h>=1024&&n.push({id:"repeated-prefix",part:t.parts.tools>t.parts.system?"tools":"system",title:"The same system prompt and tool definitions are re-sent on every call",evidence:`${H(h)} tokens (${ua(h,s)} of the latest call) repeated on ${i} calls: ${H(h*i)} tokens in total.`,automatic:[...c("prompt-caching","prompt caching turned on for the repeated prefix"),...g],advice:[l.has("prompt-caching")||u?"":"Keep this prefix byte-identical between calls so the provider can cache it: OpenAI and Gemini do so automatically; on a self-hosted server turn on prefix caching (vLLM --enable-prefix-caching; SGLang has it on by default).",t.parts.tools>2e3?"Send only the tools this step can use; long tool descriptions are paid for on every call.":""].filter(Boolean).join(" ")||void 0,estSavedTokensPerCall:h*.9});let E=o("history");if(i>2&&E>300&&t.parts.history/s>=.3){let y=t.parts.history;n.push({id:"growing-history",part:"history",title:"Each call re-reads a growing history",evidence:`History grows about ${H(E)} tokens per call and is now ${H(y)} tokens (${ua(y,s)} of the latest call). Over ${i} calls the model re-read ${H(Z(e.map(x=>x.parts.history)))} history tokens.`,automatic:[...c("prompt-caching","the history so far is cached between calls"),...g],advice:"Start long runs from a summary instead of the full transcript (Token Lens's handoff brief), or keep only the turns the next step needs.",estSavedTokensPerCall:y*.5})}let I=t.parts.tool_output/s;if(t.parts.tool_output>1e3&&(I>=.3||o("tool_output")>500)){let y=t.toolOutputs,x=Z(y.slice(0,Math.max(0,y.length-3)).filter(d=>d>=300)),K=l.get("elide-tool-outputs");n.push({id:"tool-outputs",part:"tool_output",title:"Tool outputs take a large share of every call",evidence:`${y.length} tool outputs, ${H(t.parts.tool_output)} tokens (${ua(t.parts.tool_output,s)} of the latest call)${i>1?`, growing about ${H(o("tool_output"))} tokens per call`:""}.`,automatic:[...c("minify-json","pretty-printed JSON compacted"),...c("collapse-repeats","repeated lines collapsed"),...K?c("elide-tool-outputs","older tool outputs replaced with a stub"):[]],optIn:!K&&x>0?{id:"elide-tool-outputs",how:co("elide-tool-outputs"),estSavedTokensPerCall:x}:void 0,advice:"Have tools return only the fields the agent uses, and page or truncate large results at the source.",estSavedTokensPerCall:K?0:x})}t.parts.context>2e3&&t.parts.context/s>=.4&&n.push({id:"large-context",part:"context",title:"Retrieved or pasted context dominates the newest message",evidence:`${H(t.parts.context)} tokens of material (${ua(t.parts.context,s)} of the latest call) against a ${H(t.parts.prompt)}-token instruction.`,automatic:[],advice:"Retrieve fewer or smaller chunks, drop near-duplicate chunks, or put a stable document before the question so it can be cached across calls.",estSavedTokensPerCall:t.parts.context*.3});let S=a.calls.filter(y=>y.duplicate);if(S.length){let y=a.calls.filter(x=>x.replayed).length;n.push({id:"retries",part:"calls",title:"Identical requests were sent more than once",evidence:`${S.length} of ${a.calls.length} calls repeated an earlier request word for word.`,automatic:y?[`${y} answered from the gateway's copy at no token cost`]:[],advice:y?void 0:"Only temperature-0 requests are replayed automatically. Check the retry loop: a retry after a timeout or a parse error re-pays the whole input.",estSavedTokensPerCall:y?0:Z(S.map(x=>x.input))/a.calls.length})}let N=Z(e.map(y=>y.usage.reasoningTokens??0)),V=Z(e.map(y=>y.usage.outputTokens??0));N>2e3&&N>.6*V&&n.push({id:"reasoning-heavy",part:"output",title:"Hidden reasoning is most of the output",evidence:`${H(N)} of ${H(V)} output tokens (${ua(N,V)}) were reasoning the app never sees.`,automatic:[],advice:"Not changed automatically, since it could change answers. If some steps are simple (routing, extraction, formatting), try a lower reasoning effort on those steps with output checks on; the model stays the same.",estSavedTokensPerCall:0});let O=t.repeatedToolCalls,L=Z(O.map(y=>y.count-1));if(L>0){let y=Z(e.map(K=>K.input))/i,x=[...O].sort((K,d)=>d.count-K.count)[0];n.push({id:"repeated-tool-calls",part:"tool_output",title:"The agent calls the same tool with the same input more than once",evidence:`${L} repeated tool call${L>1?"s":""} in ${H(t.toolCalls)}; for example ${x.name}(${tr(x.args)}) ${x.count} times. Each repeat is an extra step that re-reads about ${H(y)} tokens of context.`,automatic:c("dedupe-tool-outputs","identical results sent once, later copies point back to the first"),advice:"Only the agent's code can skip the repeated step: cache tool results for the run (keyed by tool and input), or say in the system prompt that results don't change within a run.",estSavedTokensPerCall:L*y/i})}let ae=t.sameCallStreak;if(ae&&ae.times>=3){let y=Z(a.calls.map(x=>x.costUsd));n.push({id:"loop",part:"calls",title:"The agent looks stuck in a loop",evidence:`Its last ${ae.times} tool calls were all ${ae.name}(${tr(ae.args)}). The run has made ${a.calls.length} calls${y?` costing $${y.toFixed(4)}`:""} so far.`,automatic:a.calls.some(x=>x.overBudget)?["the run budget stopped further calls"]:[],optIn:{id:"run-budget",how:'Cap runs with "runBudget" in the gateway config, or the x-token-lens-max-calls / x-token-lens-max-cost-usd headers; calls past the cap get an error instead of being sent.'},advice:"Give the agent a step limit and a stop condition, and handle a tool error by changing the input instead of repeating the call.",estSavedTokensPerCall:(ae.times-1)*(Z(e.map(x=>x.input))/i)/i})}let Qe=Z(e.map(y=>(y.usage.outputTokens??0)*(te[y.profile]?.pricing?.outputPerMTok??0)))/1e6,Ze=Z(e.map(y=>y.costUsd)),da=Z(e.map(y=>y.usage.outputTokens??0))/i;Ze>0&&Qe/Ze>=.5&&da>500&&n.push({id:"output-heavy",part:"output",title:"Generated output is most of this run's cost",evidence:`Output is ${ua(Qe,Ze)} of the run's cost, about ${H(da)} tokens per step.`,automatic:[],advice:"Not changed automatically, since it shapes the answer. Asking intermediate steps for structured or brief output (and setting max_tokens on them) usually cuts this without changing the final result; check it with output checks on.",estSavedTokensPerCall:0});let be=t.images;be&&be.count&&(be.tokens>=1500||be.count>=3)&&n.push({id:"images",part:"context",title:"Images are re-sent on every call",evidence:`${be.count} image${be.count>1?"s":""} in the latest call, about ${H(be.tokens)} tokens (estimated from their sizes), ${H(be.oldTokens)} of them in older messages. ${be.provider==="anthropic"?"Anthropic shrinks images to 1,568 px":"OpenAI shrinks images to 2,048 px and a 768 px short side"} before counting, so sending them smaller than that saves upload time, not tokens.`,automatic:c("dedupe-images","a repeated image sent once"),advice:"Once the model has used an image, keep its description instead of the image; crop to the part that matters.",estSavedTokensPerCall:be.oldTokens});let Pe=e.filter(y=>y.cacheBreak),ce=Pe.at(-1)?.cacheBreak;if(ce&&Pe.length>=Math.max(1,(i-1)/3)){let y=Z(Pe.map(K=>K.cacheBreak.tokens)),x=ce.kind==="changed text"?"text that changes":ce.kind==="number"?"a number that changes":`a ${ce.kind}`;n.push({id:"cache-breaker",part:ce.where==="tools"?"tools":"system",title:ce.kind.endsWith("tools")?`The tool list ${ce.kind==="reordered tools"?"comes in a different order":"changes"} between calls, so the provider can't reuse its cache`:`The ${ce.where} contains ${x}, so the provider can't reuse its cache`,evidence:`On ${Pe.length} of ${i} calls the ${ce.where} started the same as the call before and then changed, so about ${H(y)} tokens that could have been read from cache (about a tenth of the price) were billed in full.`,automatic:[],advice:"Only the app can fix this, by keeping everything before the changing part identical between calls.",estSavedTokensPerCall:y/i*.9})}let ea=t.jsonRetries??0;if(ea>0&&!t.structuredOutput){let y=Z(e.map(x=>x.input))/i;n.push({id:"json-retries",part:"calls",title:"The agent re-asks the model after its JSON didn't parse",evidence:`${ea} time${ea>1?"s":""} in this conversation the model's JSON reply didn't parse and the agent asked again; each retry is a whole extra step of about ${H(y)} tokens.`,automatic:[],advice:"Strict structured output on the same model makes every reply parse.",estSavedTokensPerCall:ea*y/i})}let fe=a.sharedReads;if(fe&&fe.files>0){let y=t.toolOutputs.length?t.parts.tool_output/t.toolOutputs.length:0;n.push({id:"shared-reads",part:"tool_output",title:"Several agents read the same files separately",evidence:`${fe.files} of the ${fe.of} files or documents this run read were also read by ${fe.runs} other run${fe.runs>1?"s":""}${fe.agents.length?` (agents: ${fe.agents.join(", ")})`:""}, each paying for them again.`,automatic:[],advice:"Load shared files once and pass them to each agent, or put them at the top of every agent's prompt so the provider's cache serves them.",estSavedTokensPerCall:fe.files*y*.9/i})}let ge=t.priceTier;if(ge&&t.input>.9*ge.aboveInputTokens){let y=t.input>ge.aboveInputTokens,x=te[t.profile]?.pricing,K=x?t.input*(ge.inputPerMTok-x.inputPerMTok)/1e6:0;n.push({id:"price-tier",part:"history",title:y?"Calls are past the size where this model charges a higher rate":"Calls are about to pass the size where this model charges a higher rate",evidence:`The latest call has ${H(t.input)} input tokens; above ${H(ge.aboveInputTokens)} the whole request is billed at $${ge.inputPerMTok} in / $${ge.outputPerMTok} out per 1M tokens${x?` instead of $${x.inputPerMTok} / $${x.outputPerMTok}`:""}.${y&&K?` That adds about $${K.toFixed(4)} to this call's input alone.`:""}`,automatic:[],advice:"Hand off to a fresh call with a summary, or drop older tool outputs, before crossing the limit. The model stays the same.",estSavedTokensPerCall:y?Math.max(0,t.input-ge.aboveInputTokens):0})}t.window&&t.input/t.window>=.8&&n.push({id:"near-context-limit",part:"history",title:"The run is close to the model's context limit",evidence:`The latest call uses ${ua(t.input,t.window)} of a ${H(t.window)}-token window.`,automatic:[],advice:"Hand off to a fresh run with a summary before the provider starts truncating or rejecting calls.",estSavedTokensPerCall:0});let Ea=te[t.profile]?.pricing?.inputPerMTok??0,xe={cachingOn:l.has("prompt-caching")||u>0,bigTools:t.parts.tools>2e3,repeat:[...t.repeatedToolCalls].sort((y,x)=>x.count-y.count)[0],loop:ae&&ae.times>=3?ae:void 0,steps:i,api:t.api,breakKind:ce?.kind,breakWhere:ce?.where,tierAbove:ge?.aboveInputTokens};return n.map(y=>{let x=Math.round(y.estSavedTokensPerCall);return{...y,estSavedTokensPerCall:x,estSavedUsdPerCall:En(x*Ea/1e6),estSavedTokensPerRun:x*i,estSavedUsdPerRun:En(x*i*Ea/1e6),fixes:oo(y.id,xe)}}).sort((y,x)=>x.estSavedTokensPerCall-y.estSavedTokensPerCall)}function yi(a){let e=a.calls.filter(s=>!s.replayed&&s.status<400);if(e.length<2)return;let n=e[0].parts,i=e[e.length-1].parts,r,t=0;for(let s of Object.keys(i)){let o=i[s]-n[s];o>t&&([r,t]=[s,o])}return r}function Tn(a){let e=a.calls,n=Je();for(let r of e){let t=te[r.profile];t&&ii(n,{profile:r.priceTier?{...t,priceTier:r.priceTier}:t,status:r.status,usage:r.usage,estimatedInput:r.input,savedInput:Z(r.actions.map(s=>s.saved)),replayed:!!r.replayed,priceFactor:r.priceFactor})}let i=un(n);return{id:a.id,app:a.app,agent:a.agent,named:a.named,firstSeen:a.firstSeen,lastSeen:a.lastSeen,calls:e.length,model:e.at(-1)?.model,tokensBefore:i.inputTokensBefore+i.outputTokens+i.outputTokensAvoided,tokensAfter:i.inputTokens+i.outputTokens,savedTokens:i.savedTokens,savedTokensPct:i.savedTokensPct,costBeforeUsd:i.costBeforeUsd,costUsd:i.costUsd,savedUsd:i.savedUsd,inputTokens:i.inputTokens,outputTokens:i.outputTokens,cachedInputTokens:i.cachedInputTokens,savedInputTokens:i.savedInputTokens,growing:yi(a),checkCostUsd:En(Z(a.checks.map(r=>r.costUsd))),netSavedUsd:En(i.savedUsd-Z(a.checks.map(r=>r.costUsd))),steps:e.filter(r=>!r.replayed&&!r.overBudget).length,retriesReplayed:e.filter(r=>r.replayed).length,stoppedByBudget:e.some(r=>r.overBudget),outputCheck:Dt(a.checks)}}var En=a=>Math.round(a*1e6)/1e6;var wa=new Set(["elide-tool-outputs","lazy-tools","trim-tool-fields","compact-json","park-tool-outputs"]),vi={prompt:"prompt","minify-json":"minifyJson","collapse-repeats":"collapseRepeats","dedupe-tool-outputs":"dedupeToolOutputs","dedupe-passages":"dedupePassages","dedupe-images":"dedupeImages"},uo=a=>a in vi||wa.has(a),Cn=class{constructor(e){this.probation=e}probation;states=new Map;state(e,n){let i=`${e}\0${n}`,r=this.states.get(i);return r||this.states.set(i,r={app:e,agent:n,suspended:new Map,confirmed:new Map}),r}configFor(e,n,i,r,t){let s=this.states.get(`${n}\0${i}`),o=new Set(s?.suspended.keys()??[]);if(t)for(let u of wa)this.onProbation(n,i,[u]).length&&o.add(u);if(!o.size)return{cfg:e,allow:r};let l={...e.safe};for(let u of o)vi[u]&&(l[vi[u]]=!1);let c={...e.optIn,elideOldToolOutputs:o.has("elide-tool-outputs")?!1:e.optIn.elideOldToolOutputs,lazyTools:o.has("lazy-tools")?!1:e.optIn.lazyTools,trimToolFields:o.has("trim-tool-fields")?!1:e.optIn.trimToolFields,compactJson:o.has("compact-json")?!1:e.optIn.compactJson,parkToolOutputs:o.has("park-tool-outputs")?!1:e.optIn.parkToolOutputs};return{cfg:{...e,safe:l,optIn:c},allow:new Set([...r].filter(u=>!o.has(u)))}}onProbation(e,n,i){let r=this.states.get(`${e}\0${n}`);return i.filter(t=>wa.has(t)&&(r?.confirmed.get(t)??0)<this.probation)}confirm(e,n,i){let r=this.state(e,n);for(let t of i)wa.has(t)&&r.confirmed.set(t,(r.confirmed.get(t)??0)+1)}suspend(e,n,i,r){let t=this.state(e,n),s=i.filter(uo);for(let o of s)t.suspended.set(o,{at:r.at,similarity:r.similarity,sameToolCalls:r.sameToolCalls}),t.confirmed.delete(o);return s}isSuspended(e,n,i){return this.states.get(`${e}\0${n}`)?.suspended.has(i)??!1}reset(e,n){let i=0;for(let[r,t]of this.states)(!e||t.app===e)&&(n===void 0||t.agent===n)&&(i+=t.suspended.size,this.states.delete(r));return i}replaceSuspended(e){for(let n of this.states.values())n.suspended.clear();for(let n of e){let i=this.state(n.app,n.agent);i.suspended.set(n.fix,{at:n.since,similarity:n.similarity,sameToolCalls:n.sameToolCalls}),i.confirmed.delete(n.fix)}}list(){let e=[];for(let n of this.states.values())for(let[i,r]of n.suspended)e.push({app:n.app,agent:n.agent,fix:i,since:r.at,similarity:r.similarity,sameToolCalls:r.sameToolCalls});return e}};import{createHash as mo}from"node:crypto";var Sa=class{constructor(e){this.maxBytes=e}maxBytes;items=new Map;bytes=0;hits=0;misses=0;static scope(e,n,i){return[e,n,i.model,i.dimensions??"",i.encoding_format??"float",i.user??""].join("\0")}static key(e,n){return mo("sha256").update(e).update("\0").update(JSON.stringify(n)).digest("hex")}get(e){let n=this.items.get(e);if(n!==void 0)return this.items.delete(e),this.items.set(e,n),JSON.parse(n)}set(e,n){let i=JSON.stringify(n);if(i.length>this.maxBytes)return;let r=this.items.get(e);for(r!==void 0&&(this.bytes-=r.length),this.items.delete(e),this.items.set(e,i),this.bytes+=i.length;this.bytes>this.maxBytes;){let[t,s]=this.items.entries().next().value;this.items.delete(t),this.bytes-=s.length}}get size(){return this.items.size}};function rr(a){let e=a.input;return typeof e=="string"?[e]:Array.isArray(e)&&e.length&&(e.every(n=>typeof n=="string")||e.every(n=>Array.isArray(n)))?e:Array.isArray(e)&&e.length&&e.every(n=>typeof n=="number")?[e]:null}import{createHash as lr}from"node:crypto";var wi=a=>lr("sha256").update(a).digest("hex").slice(0,8),_a=256,sr=a=>{let e=[];for(let n=0;n<a.length;n+=_a)e.push(wi(a.slice(n,n+_a)));return e};function cr(a,e,n){return{system:sr(a),tools:sr(e.join(`
3353
- `)),toolOrder:wi(n.join("\0")),toolSet:wi([...n].sort().join("\0"))}}function or(a){return/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}|\b\d{1,2}:\d{2}(:\d{2})?\s*(am|pm|utc|gmt)?\b|\b1[6-9]\d{8}(\d{3})?\b/i.test(a)?"timestamp":/\b\d{4}-\d{2}-\d{2}\b|\b(mon|tue|wed|thu|fri|sat|sun)[a-z]*,? \w+ \d{1,2}|\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]* \d{1,2},? \d{4}|\btoday is\b/i.test(a)?"date":/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b|\b[0-9a-f]{16,}\b|\b(req|run|session|trace|user)[-_][a-z0-9]{6,}\b/i.test(a)?"id":/\d{3,}/.test(a)?"number":"changed text"}function ur(a,e,n,i){if(!a)return;let r=e.system.length+e.tools.length;if(!r)return;let t=(l,c)=>{let u=Math.min(l.length,c.length);for(let g=0;g<u;g++)if(l[g]!==c[g])return g;return l.length===c.length?-1:u},s=t(a.system,e.system);if(s>=0){if(e.system.filter(u=>a.system.includes(u)).length/Math.max(e.system.length,1)<.5)return;let c=s*_a;return{kind:or(n.slice(Math.max(0,c-40),c+_a+40)),where:"system prompt",lostShare:(r-s)/r}}if(a.toolOrder!==e.toolOrder&&a.toolSet===e.toolSet)return{kind:"reordered tools",where:"tools",lostShare:e.tools.length/r};let o=t(a.tools,e.tools);if(o>=0&&a.toolSet===e.toolSet){let l=o*_a,c=or(i.slice(Math.max(0,l-40),l+_a+40));return{kind:c==="changed text"?"changed tools":c,where:"tools",lostShare:(e.tools.length-o)/r}}}function po(a,e){let n=r=>typeof r=="string"?r:Array.isArray(r)?r.map(t=>typeof t=="string"?t:typeof t?.text=="string"?t.text:typeof t?.content=="string"?t.content:Array.isArray(t?.content)?n(t.content):"").join(`
3354
- `):"";return(a==="openai-responses"?Array.isArray(e?.input)?e.input:[]:Array.isArray(e?.messages)?e.messages:[]).map(r=>({role:r?.role??(r?.type==="function_call_output"?"tool":r?.type??""),text:n(r?.content??r?.output)}))}var go=a=>/^\s*(```(json)?\s*)?[{[]/i.test(a),ho=a=>{try{return JSON.parse(a.trim().replace(/^```(json)?\s*/i,"").replace(/```\s*$/,"")),!0}catch{return!1}};function dr(a,e){let n=po(a,e),i=0;return n.forEach((r,t)=>{let s=n[t+1];r.role==="assistant"&&go(r.text)&&!ho(r.text)&&s&&s.role!=="assistant"&&/json|pars|valid|format|schema/i.test(s.text)&&i++}),i}function mr(a,e){return a==="openai-chat"?e?.response_format?.type==="json_schema":a==="openai-responses"?e?.text?.format?.type==="json_schema":!!e?.output_format||e?.tool_choice?.type==="tool"&&Array.isArray(e?.tools)}var bo=/(^|[_.\-\s])(read|open|cat|view|load|get)([_.\-\s]?(file|doc|document|page|text))?($|[_.\-\s])|^read|file$/i,fo=["path","file","file_path","filepath","filename","uri","url","document_id","doc_id"];function pr(a){let e=new Set;for(let n of a){if(!bo.test(n.name))continue;let i;try{i=JSON.parse(n.args)}catch{continue}let r=i&&typeof i=="object"?fo.map(t=>i[t]).find(t=>typeof t=="string"&&t.length>0):void 0;r&&e.add(lr("sha256").update(r).digest("hex").slice(0,16))}return[...e]}var ko=a=>new RegExp("^"+a.split("*").map(e=>e.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*")+"$","i");function gr(a,e){return a.find(n=>ko(n.model).test(e))}import{readFileSync as yo,renameSync as vo,writeFileSync as wo}from"node:fs";import{connect as So}from"node:net";import{connect as _o}from"node:tls";var Ha=class{constructor(e){this.url=e}url;socket;ready;buf=Buffer.alloc(0);waiting=[];connect(){if(this.ready)return this.ready;let e=new URL(this.url),n=Number(e.port)||6379,i=e.hostname||"127.0.0.1";return this.ready=new Promise((r,t)=>{let s=e.protocol==="rediss:"?_o({host:i,port:n,servername:i},()=>r()):So({host:i,port:n},()=>r());s.on("error",o=>{t(o),this.fail(o)}),s.on("close",()=>this.fail(new Error("Redis connection closed"))),s.on("data",o=>this.data(o)),s.unref(),this.socket=s}).then(async()=>{e.password&&await this.raw(e.username?["AUTH",decodeURIComponent(e.username),decodeURIComponent(e.password)]:["AUTH",decodeURIComponent(e.password)]);let r=e.pathname.replace("/","");r&&await this.raw(["SELECT",r])}),this.ready}fail(e){this.ready=void 0,this.socket=void 0,this.buf=Buffer.alloc(0);for(let n of this.waiting.splice(0))n.reject(e)}raw(e){return new Promise((n,i)=>{this.waiting.push({resolve:n,reject:i});let r=e.map(t=>Buffer.from(String(t)));this.socket.write(Buffer.concat([Buffer.from(`*${r.length}\r
3355
+ await Promise.all(subAgents.map((a) => a.run({ task, context: docs })));`},{where:"agent code",what:"Or share one read cache between sub-agents",apply:'const cache = new Map(); const readOnce = (p) => cache.get(p) ?? (cache.set(p, fs.promises.readFile(p, "utf8")), cache.get(p));'},{where:"agent code",what:"Put the shared files in the same place at the top of each sub-agent's prompt, so the provider's cache serves them after the first",apply:'system: [STATIC_SYSTEM, ...docs.map((d) => `<doc path="${d.path}">${d.text}</doc>`)].join("\\n")'}];case"price-tier":return[{where:"agent code",what:`Keep each request under ${K(e.tierAbove??2e5)} input tokens: hand off to a fresh call with a summary first`,apply:`if (estimateTokens(messages) > ${Math.round((e.tierAbove??2e5)*.9)}) messages = [system, { role: "user", content: await summarize(messages) }];`},{where:"request header",what:"Replace older tool outputs with a stub (opt-in; answers checked before it applies)",apply:"x-token-lens-allow: elide-tool-outputs"},{where:"agent code",what:"Retrieve fewer, smaller chunks",apply:"const chunks = await search(query, { topK: 4, maxTokensPerChunk: 400 });"}];case"near-context-limit":return[{where:"agent code",what:"Hand off to a fresh run with a summary before the window fills",apply:'if (usage.input_tokens > 0.7 * CONTEXT_WINDOW) messages = [system, { role: "user", content: await summarize(messages) }];'}];default:return[]}}var K=a=>Math.round(a).toLocaleString("en-US"),ba=(a,e)=>`${e?Math.round(a/e*100):0}%`,te=a=>a.reduce((e,n)=>e+n,0),Pr=a=>a.length>60?a.slice(0,57)+"...":a;function Bo(a){let e=new Map;for(let n of a)for(let i of n.actions){let r=e.get(i.id)??{saved:0,calls:0};r.saved+=i.saved,r.calls++,e.set(i.id,r)}return e}var Fo=a=>`Send the header "x-token-lens-allow: ${a}" on this app's requests, or enable it for everyone in the gateway config.`;function Ln(a){let e=a.calls.filter(S=>!S.replayed&&S.status<400),n=[];if(!e.length)return[];let i=e.length,r=e[0],t=e[i-1],s=t.input||1,o=S=>i>1?(t.parts[S]-r.parts[S])/(i-1):0,l=Bo(a.calls),c=(S,j)=>{let X=l.get(S);return X?[`${j} (${X.calls} of ${a.calls.length} calls${X.saved?`, ${K(X.saved)} tokens saved so far`:""})`]:[]},u=te(e.map(S=>S.usage.cachedInputTokens??0)),g=u?[`provider reports ${K(u)} input tokens served from cache`]:[],h=t.parts.system+t.parts.tools;i>1&&h>=1024&&n.push({id:"repeated-prefix",part:t.parts.tools>t.parts.system?"tools":"system",title:"The same system prompt and tool definitions are re-sent on every call",evidence:`${K(h)} tokens (${ba(h,s)} of the latest call) repeated on ${i} calls: ${K(h*i)} tokens in total.`,automatic:[...c("prompt-caching","prompt caching turned on for the repeated prefix"),...g],advice:[l.has("prompt-caching")||u?"":"Keep this prefix byte-identical between calls so the provider can cache it: OpenAI and Gemini do so automatically; on a self-hosted server turn on prefix caching (vLLM --enable-prefix-caching; SGLang has it on by default).",t.parts.tools>2e3?"Send only the tools this step can use; long tool descriptions are paid for on every call.":""].filter(Boolean).join(" ")||void 0,estSavedTokensPerCall:h*.9});let y=o("history");if(i>2&&y>300&&t.parts.history/s>=.3){let S=t.parts.history;n.push({id:"growing-history",part:"history",title:"Each call re-reads a growing history",evidence:`History grows about ${K(y)} tokens per call and is now ${K(S)} tokens (${ba(S,s)} of the latest call). Over ${i} calls the model re-read ${K(te(e.map(j=>j.parts.history)))} history tokens.`,automatic:[...c("prompt-caching","the history so far is cached between calls"),...g],advice:"Start long runs from a summary instead of the full transcript (Token Lens's handoff brief), or keep only the turns the next step needs.",estSavedTokensPerCall:S*.5})}let I=t.parts.tool_output/s;if(t.parts.tool_output>1e3&&(I>=.3||o("tool_output")>500)){let S=t.toolOutputs,j=te(S.slice(0,Math.max(0,S.length-3)).filter(ka=>ka>=300)),X=l.get("elide-tool-outputs");n.push({id:"tool-outputs",part:"tool_output",title:"Tool outputs take a large share of every call",evidence:`${S.length} tool outputs, ${K(t.parts.tool_output)} tokens (${ba(t.parts.tool_output,s)} of the latest call)${i>1?`, growing about ${K(o("tool_output"))} tokens per call`:""}.`,automatic:[...c("minify-json","pretty-printed JSON compacted"),...c("collapse-repeats","repeated lines collapsed"),...X?c("elide-tool-outputs","older tool outputs replaced with a stub"):[]],optIn:!X&&j>0?{id:"elide-tool-outputs",how:Fo("elide-tool-outputs"),estSavedTokensPerCall:j}:void 0,advice:"Have tools return only the fields the agent uses, and page or truncate large results at the source.",estSavedTokensPerCall:X?0:j})}t.parts.context>2e3&&t.parts.context/s>=.4&&n.push({id:"large-context",part:"context",title:"Retrieved or pasted context dominates the newest message",evidence:`${K(t.parts.context)} tokens of material (${ba(t.parts.context,s)} of the latest call) against a ${K(t.parts.prompt)}-token instruction.`,automatic:[],advice:"Retrieve fewer or smaller chunks, drop near-duplicate chunks, or put a stable document before the question so it can be cached across calls.",estSavedTokensPerCall:t.parts.context*.3});let E=a.calls.filter(S=>S.duplicate);if(E.length){let S=a.calls.filter(j=>j.replayed).length;n.push({id:"retries",part:"calls",title:"Identical requests were sent more than once",evidence:`${E.length} of ${a.calls.length} calls repeated an earlier request word for word.`,automatic:S?[`${S} answered from the gateway's copy at no token cost`]:[],advice:S?void 0:"Only temperature-0 requests are replayed automatically. Check the retry loop: a retry after a timeout or a parse error re-pays the whole input.",estSavedTokensPerCall:S?0:te(E.map(j=>j.input))/a.calls.length})}let H=te(e.map(S=>S.usage.reasoningTokens??0)),W=te(e.map(S=>S.usage.outputTokens??0));H>2e3&&H>.6*W&&n.push({id:"reasoning-heavy",part:"output",title:"Hidden reasoning is most of the output",evidence:`${K(H)} of ${K(W)} output tokens (${ba(H,W)}) were reasoning the app never sees.`,automatic:[],advice:"Not changed automatically, since it could change answers. If some steps are simple (routing, extraction, formatting), try a lower reasoning effort on those steps with output checks on; the model stays the same.",estSavedTokensPerCall:0});let L=t.repeatedToolCalls,F=te(L.map(S=>S.count-1));if(F>0){let S=te(e.map(X=>X.input))/i,j=[...L].sort((X,ka)=>ka.count-X.count)[0];n.push({id:"repeated-tool-calls",part:"tool_output",title:"The agent calls the same tool with the same input more than once",evidence:`${F} repeated tool call${F>1?"s":""} in ${K(t.toolCalls)}; for example ${j.name}(${Pr(j.args)}) ${j.count} times. Each repeat is an extra step that re-reads about ${K(S)} tokens of context.`,automatic:c("dedupe-tool-outputs","identical results sent once, later copies point back to the first"),advice:"Only the agent's code can skip the repeated step: cache tool results for the run (keyed by tool and input), or say in the system prompt that results don't change within a run.",estSavedTokensPerCall:F*S/i})}let ee=t.sameCallStreak;if(ee&&ee.times>=3){let S=te(a.calls.map(j=>j.costUsd));n.push({id:"loop",part:"calls",title:"The agent looks stuck in a loop",evidence:`Its last ${ee.times} tool calls were all ${ee.name}(${Pr(ee.args)}). The run has made ${a.calls.length} calls${S?` costing $${S.toFixed(4)}`:""} so far.`,automatic:a.calls.some(j=>j.overBudget)?["the run budget stopped further calls"]:[],optIn:{id:"run-budget",how:'Cap runs with "runBudget" in the gateway config, or the x-token-lens-max-calls / x-token-lens-max-cost-usd headers; calls past the cap get an error instead of being sent.'},advice:"Give the agent a step limit and a stop condition, and handle a tool error by changing the input instead of repeating the call.",estSavedTokensPerCall:(ee.times-1)*(te(e.map(j=>j.input))/i)/i})}let an=te(e.map(S=>(S.usage.outputTokens??0)*(se[S.profile]?.pricing?.outputPerMTok??0)))/1e6,Te=te(e.map(S=>S.costUsd)),Ne=te(e.map(S=>S.usage.outputTokens??0))/i;Te>0&&an/Te>=.5&&Ne>500&&n.push({id:"output-heavy",part:"output",title:"Generated output is most of this run's cost",evidence:`Output is ${ba(an,Te)} of the run's cost, about ${K(Ne)} tokens per step.`,automatic:[],advice:"Not changed automatically, since it shapes the answer. Asking intermediate steps for structured or brief output (and setting max_tokens on them) usually cuts this without changing the final result; check it with output checks on.",estSavedTokensPerCall:0});let me=t.images;me&&me.count&&(me.tokens>=1500||me.count>=3)&&n.push({id:"images",part:"context",title:"Images are re-sent on every call",evidence:`${me.count} image${me.count>1?"s":""} in the latest call, about ${K(me.tokens)} tokens (estimated from their sizes), ${K(me.oldTokens)} of them in older messages. ${me.provider==="anthropic"?"Anthropic shrinks images to 1,568 px":"OpenAI shrinks images to 2,048 px and a 768 px short side"} before counting, so sending them smaller than that saves upload time, not tokens.`,automatic:c("dedupe-images","a repeated image sent once"),advice:"Once the model has used an image, keep its description instead of the image; crop to the part that matters.",estSavedTokensPerCall:me.oldTokens});let We=e.filter(S=>S.cacheBreak),pe=We.at(-1)?.cacheBreak;if(pe&&We.length>=Math.max(1,(i-1)/3)){let S=te(We.map(X=>X.cacheBreak.tokens)),j=pe.kind==="changed text"?"text that changes":pe.kind==="number"?"a number that changes":`a ${pe.kind}`;n.push({id:"cache-breaker",part:pe.where==="tools"?"tools":"system",title:pe.kind.endsWith("tools")?`The tool list ${pe.kind==="reordered tools"?"comes in a different order":"changes"} between calls, so the provider can't reuse its cache`:`The ${pe.where} contains ${j}, so the provider can't reuse its cache`,evidence:`On ${We.length} of ${i} calls the ${pe.where} started the same as the call before and then changed, so about ${K(S)} tokens that could have been read from cache (about a tenth of the price) were billed in full.`,automatic:[],advice:"Only the app can fix this, by keeping everything before the changing part identical between calls.",estSavedTokensPerCall:S/i*.9})}let Ke=t.jsonRetries??0;if(Ke>0&&!t.structuredOutput){let S=te(e.map(j=>j.input))/i;n.push({id:"json-retries",part:"calls",title:"The agent re-asks the model after its JSON didn't parse",evidence:`${Ke} time${Ke>1?"s":""} in this conversation the model's JSON reply didn't parse and the agent asked again; each retry is a whole extra step of about ${K(S)} tokens.`,automatic:[],advice:"Strict structured output on the same model makes every reply parse.",estSavedTokensPerCall:Ke*S/i})}let be=a.sharedReads;if(be&&be.files>0){let S=t.toolOutputs.length?t.parts.tool_output/t.toolOutputs.length:0;n.push({id:"shared-reads",part:"tool_output",title:"Several agents read the same files separately",evidence:`${be.files} of the ${be.of} files or documents this run read were also read by ${be.runs} other run${be.runs>1?"s":""}${be.agents.length?` (agents: ${be.agents.join(", ")})`:""}, each paying for them again.`,automatic:[],advice:"Load shared files once and pass them to each agent, or put them at the top of every agent's prompt so the provider's cache serves them.",estSavedTokensPerCall:be.files*S*.9/i})}let Ce=t.priceTier;if(Ce&&t.input>.9*Ce.aboveInputTokens){let S=t.input>Ce.aboveInputTokens,j=se[t.profile]?.pricing,X=j?t.input*(Ce.inputPerMTok-j.inputPerMTok)/1e6:0;n.push({id:"price-tier",part:"history",title:S?"Calls are past the size where this model charges a higher rate":"Calls are about to pass the size where this model charges a higher rate",evidence:`The latest call has ${K(t.input)} input tokens; above ${K(Ce.aboveInputTokens)} the whole request is billed at $${Ce.inputPerMTok} in / $${Ce.outputPerMTok} out per 1M tokens${j?` instead of $${j.inputPerMTok} / $${j.outputPerMTok}`:""}.${S&&X?` That adds about $${X.toFixed(4)} to this call's input alone.`:""}`,automatic:[],advice:"Hand off to a fresh call with a summary, or drop older tool outputs, before crossing the limit. The model stays the same.",estSavedTokensPerCall:S?Math.max(0,t.input-Ce.aboveInputTokens):0})}t.window&&t.input/t.window>=.8&&n.push({id:"near-context-limit",part:"history",title:"The run is close to the model's context limit",evidence:`The latest call uses ${ba(t.input,t.window)} of a ${K(t.window)}-token window.`,automatic:[],advice:"Hand off to a fresh run with a summary before the provider starts truncating or rejecting calls.",estSavedTokensPerCall:0});let $e=se[t.profile]?.pricing?.inputPerMTok??0,nn={cachingOn:l.has("prompt-caching")||u>0,bigTools:t.parts.tools>2e3,repeat:[...t.repeatedToolCalls].sort((S,j)=>j.count-S.count)[0],loop:ee&&ee.times>=3?ee:void 0,steps:i,api:t.api,breakKind:pe?.kind,breakWhere:pe?.where,tierAbove:Ce?.aboveInputTokens};return n.map(S=>{let j=Math.round(S.estSavedTokensPerCall);return{...S,estSavedTokensPerCall:j,estSavedUsdPerCall:Nn(j*$e/1e6),estSavedTokensPerRun:j*i,estSavedUsdPerRun:Nn(j*i*$e/1e6),fixes:Lo(S.id,nn)}}).sort((S,j)=>j.estSavedTokensPerCall-S.estSavedTokensPerCall)}function ji(a){let e=a.calls.filter(s=>!s.replayed&&s.status<400);if(e.length<2)return;let n=e[0].parts,i=e[e.length-1].parts,r,t=0;for(let s of Object.keys(i)){let o=i[s]-n[s];o>t&&([r,t]=[s,o])}return r}function Bn(a){let e=a.calls,n=fe();for(let r of e){let t=se[r.profile];t&&ja(n,{profile:r.priceTier?{...t,priceTier:r.priceTier}:t,status:r.status,usage:r.usage,estimatedInput:r.input,savedInput:te(r.actions.map(s=>s.saved)),replayed:!!r.replayed,priceFactor:r.priceFactor})}let i=Sa(n);return{id:a.id,app:a.app,agent:a.agent,...a.customer?{customer:a.customer}:{},named:a.named,firstSeen:a.firstSeen,lastSeen:a.lastSeen,calls:e.length,model:e.at(-1)?.model,tokensBefore:i.inputTokensBefore+i.outputTokens+i.outputTokensAvoided,tokensAfter:i.inputTokens+i.outputTokens,savedTokens:i.savedTokens,savedTokensPct:i.savedTokensPct,costBeforeUsd:i.costBeforeUsd,costUsd:i.costUsd,savedUsd:i.savedUsd,inputTokens:i.inputTokens,outputTokens:i.outputTokens,cachedInputTokens:i.cachedInputTokens,savedInputTokens:i.savedInputTokens,growing:ji(a),checkCostUsd:Nn(te(a.checks.map(r=>r.costUsd))),netSavedUsd:Nn(i.savedUsd-te(a.checks.map(r=>r.costUsd))),steps:e.filter(r=>!r.replayed&&!r.overBudget).length,retriesReplayed:e.filter(r=>r.replayed).length,stoppedByBudget:e.some(r=>r.overBudget),outputCheck:or(a.checks)}}var Nn=a=>Math.round(a*1e6)/1e6;var za=new Set(["elide-tool-outputs","lazy-tools","trim-tool-fields","compact-json","park-tool-outputs"]),Oi={prompt:"prompt","minify-json":"minifyJson","collapse-repeats":"collapseRepeats","dedupe-tool-outputs":"dedupeToolOutputs","dedupe-passages":"dedupePassages","dedupe-images":"dedupeImages"},Go=a=>a in Oi||za.has(a),Fn=class{constructor(e){this.probation=e}probation;states=new Map;state(e,n){let i=`${e}\0${n}`,r=this.states.get(i);return r||this.states.set(i,r={app:e,agent:n,suspended:new Map,confirmed:new Map}),r}configFor(e,n,i,r,t){let s=this.states.get(`${n}\0${i}`),o=new Set(s?.suspended.keys()??[]);if(t)for(let u of za)this.onProbation(n,i,[u]).length&&o.add(u);if(!o.size)return{cfg:e,allow:r};let l={...e.safe};for(let u of o)Oi[u]&&(l[Oi[u]]=!1);let c={...e.optIn,elideOldToolOutputs:o.has("elide-tool-outputs")?!1:e.optIn.elideOldToolOutputs,lazyTools:o.has("lazy-tools")?!1:e.optIn.lazyTools,trimToolFields:o.has("trim-tool-fields")?!1:e.optIn.trimToolFields,compactJson:o.has("compact-json")?!1:e.optIn.compactJson,parkToolOutputs:o.has("park-tool-outputs")?!1:e.optIn.parkToolOutputs};return{cfg:{...e,safe:l,optIn:c},allow:new Set([...r].filter(u=>!o.has(u)))}}onProbation(e,n,i){let r=this.states.get(`${e}\0${n}`);return i.filter(t=>za.has(t)&&(r?.confirmed.get(t)??0)<this.probation)}confirm(e,n,i){let r=this.state(e,n);for(let t of i)za.has(t)&&r.confirmed.set(t,(r.confirmed.get(t)??0)+1)}suspend(e,n,i,r){let t=this.state(e,n),s=i.filter(Go);for(let o of s)t.suspended.set(o,{at:r.at,similarity:r.similarity,sameToolCalls:r.sameToolCalls}),t.confirmed.delete(o);return s}isSuspended(e,n,i){return this.states.get(`${e}\0${n}`)?.suspended.has(i)??!1}reset(e,n){let i=0;for(let[r,t]of this.states)(!e||t.app===e)&&(n===void 0||t.agent===n)&&(i+=t.suspended.size,this.states.delete(r));return i}replaceSuspended(e){for(let n of this.states.values())n.suspended.clear();for(let n of e){let i=this.state(n.app,n.agent);i.suspended.set(n.fix,{at:n.since,similarity:n.similarity,sameToolCalls:n.sameToolCalls}),i.confirmed.delete(n.fix)}}list(){let e=[];for(let n of this.states.values())for(let[i,r]of n.suspended)e.push({app:n.app,agent:n.agent,fix:i,since:r.at,similarity:r.similarity,sameToolCalls:r.sameToolCalls});return e}};import{createHash as qo}from"node:crypto";var Ia=class{constructor(e){this.maxBytes=e}maxBytes;items=new Map;bytes=0;hits=0;misses=0;static scope(e,n,i){return[e,n,i.model,i.dimensions??"",i.encoding_format??"float",i.user??""].join("\0")}static key(e,n){return qo("sha256").update(e).update("\0").update(JSON.stringify(n)).digest("hex")}get(e){let n=this.items.get(e);if(n!==void 0)return this.items.delete(e),this.items.set(e,n),JSON.parse(n)}set(e,n){let i=JSON.stringify(n);if(i.length>this.maxBytes)return;let r=this.items.get(e);for(r!==void 0&&(this.bytes-=r.length),this.items.delete(e),this.items.set(e,i),this.bytes+=i.length;this.bytes>this.maxBytes;){let[t,s]=this.items.entries().next().value;this.items.delete(t),this.bytes-=s.length}}get size(){return this.items.size}};function zr(a){let e=a.input;return typeof e=="string"?[e]:Array.isArray(e)&&e.length&&(e.every(n=>typeof n=="string")||e.every(n=>Array.isArray(n)))?e:Array.isArray(e)&&e.length&&e.every(n=>typeof n=="number")?[e]:null}import{createHash as Mr}from"node:crypto";var Di=a=>Mr("sha256").update(a).digest("hex").slice(0,8),xa=256,Ir=a=>{let e=[];for(let n=0;n<a.length;n+=xa)e.push(Di(a.slice(n,n+xa)));return e};function jr(a,e,n){return{system:Ir(a),tools:Ir(e.join(`
3356
+ `)),toolOrder:Di(n.join("\0")),toolSet:Di([...n].sort().join("\0"))}}function xr(a){return/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}|\b\d{1,2}:\d{2}(:\d{2})?\s*(am|pm|utc|gmt)?\b|\b1[6-9]\d{8}(\d{3})?\b/i.test(a)?"timestamp":/\b\d{4}-\d{2}-\d{2}\b|\b(mon|tue|wed|thu|fri|sat|sun)[a-z]*,? \w+ \d{1,2}|\b(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]* \d{1,2},? \d{4}|\btoday is\b/i.test(a)?"date":/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b|\b[0-9a-f]{16,}\b|\b(req|run|session|trace|user)[-_][a-z0-9]{6,}\b/i.test(a)?"id":/\d{3,}/.test(a)?"number":"changed text"}function Or(a,e,n,i){if(!a)return;let r=e.system.length+e.tools.length;if(!r)return;let t=(l,c)=>{let u=Math.min(l.length,c.length);for(let g=0;g<u;g++)if(l[g]!==c[g])return g;return l.length===c.length?-1:u},s=t(a.system,e.system);if(s>=0){if(e.system.filter(u=>a.system.includes(u)).length/Math.max(e.system.length,1)<.5)return;let c=s*xa;return{kind:xr(n.slice(Math.max(0,c-40),c+xa+40)),where:"system prompt",lostShare:(r-s)/r}}if(a.toolOrder!==e.toolOrder&&a.toolSet===e.toolSet)return{kind:"reordered tools",where:"tools",lostShare:e.tools.length/r};let o=t(a.tools,e.tools);if(o>=0&&a.toolSet===e.toolSet){let l=o*xa,c=xr(i.slice(Math.max(0,l-40),l+xa+40));return{kind:c==="changed text"?"changed tools":c,where:"tools",lostShare:(e.tools.length-o)/r}}}function Uo(a,e){let n=r=>typeof r=="string"?r:Array.isArray(r)?r.map(t=>typeof t=="string"?t:typeof t?.text=="string"?t.text:typeof t?.content=="string"?t.content:Array.isArray(t?.content)?n(t.content):"").join(`
3357
+ `):"";return(a==="openai-responses"?Array.isArray(e?.input)?e.input:[]:Array.isArray(e?.messages)?e.messages:[]).map(r=>({role:r?.role??(r?.type==="function_call_output"?"tool":r?.type??""),text:n(r?.content??r?.output)}))}var Ho=a=>/^\s*(```(json)?\s*)?[{[]/i.test(a),Vo=a=>{try{return JSON.parse(a.trim().replace(/^```(json)?\s*/i,"").replace(/```\s*$/,"")),!0}catch{return!1}};function Dr(a,e){let n=Uo(a,e),i=0;return n.forEach((r,t)=>{let s=n[t+1];r.role==="assistant"&&Ho(r.text)&&!Vo(r.text)&&s&&s.role!=="assistant"&&/json|pars|valid|format|schema/i.test(s.text)&&i++}),i}function Nr(a,e){return a==="openai-chat"?e?.response_format?.type==="json_schema":a==="openai-responses"?e?.text?.format?.type==="json_schema":!!e?.output_format||e?.tool_choice?.type==="tool"&&Array.isArray(e?.tools)}var Wo=/(^|[_.\-\s])(read|open|cat|view|load|get)([_.\-\s]?(file|doc|document|page|text))?($|[_.\-\s])|^read|file$/i,Ko=["path","file","file_path","filepath","filename","uri","url","document_id","doc_id"];function Lr(a){let e=new Set;for(let n of a){if(!Wo.test(n.name))continue;let i;try{i=JSON.parse(n.args)}catch{continue}let r=i&&typeof i=="object"?Ko.map(t=>i[t]).find(t=>typeof t=="string"&&t.length>0):void 0;r&&e.add(Mr("sha256").update(r).digest("hex").slice(0,16))}return[...e]}var $o=a=>new RegExp("^"+a.split("*").map(e=>e.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*")+"$","i");function Br(a,e){return a.find(n=>$o(n.model).test(e))}import{readFileSync as Jo,renameSync as Yo,writeFileSync as Xo}from"node:fs";import{connect as Qo}from"node:net";import{connect as Zo}from"node:tls";var Za=class{constructor(e){this.url=e}url;socket;ready;buf=Buffer.alloc(0);waiting=[];connect(){if(this.ready)return this.ready;let e=new URL(this.url),n=Number(e.port)||6379,i=e.hostname||"127.0.0.1";return this.ready=new Promise((r,t)=>{let s=e.protocol==="rediss:"?Zo({host:i,port:n,servername:i},()=>r()):Qo({host:i,port:n},()=>r());s.on("error",o=>{t(o),this.fail(o)}),s.on("close",()=>this.fail(new Error("Redis connection closed"))),s.on("data",o=>this.data(o)),s.unref(),this.socket=s}).then(async()=>{e.password&&await this.raw(e.username?["AUTH",decodeURIComponent(e.username),decodeURIComponent(e.password)]:["AUTH",decodeURIComponent(e.password)]);let r=e.pathname.replace("/","");r&&await this.raw(["SELECT",r])}),this.ready}fail(e){this.ready=void 0,this.socket=void 0,this.buf=Buffer.alloc(0);for(let n of this.waiting.splice(0))n.reject(e)}raw(e){return new Promise((n,i)=>{this.waiting.push({resolve:n,reject:i});let r=e.map(t=>Buffer.from(String(t)));this.socket.write(Buffer.concat([Buffer.from(`*${r.length}\r
3355
3358
  `),...r.flatMap(t=>[Buffer.from(`$${t.length}\r
3356
3359
  `),t,Buffer.from(`\r
3357
- `)])]))})}async cmd(...e){await this.connect();let n=await this.raw(e);if(n instanceof Error)throw n;return n}data(e){for(this.buf=Buffer.concat([this.buf,e]);;){let n=hr(this.buf,0);if(!n)return;this.buf=this.buf.subarray(n.end),this.waiting.shift()?.resolve(n.value)}}async hincrbyfloat(e,n,i){await this.cmd("HINCRBYFLOAT",e,n,i)}async hgetall(e){let n=await this.cmd("HGETALL",e),i={};for(let r=0;r+1<n.length;r+=2)i[n[r]]=n[r+1];return i}async hset(e,n,i){await this.cmd("HSET",e,n,i)}async hdel(e,n){await this.cmd("HDEL",e,n)}async setex(e,n,i){await this.cmd("SET",e,i,"EX",Math.max(1,Math.round(n)))}async get(e){return await this.cmd("GET",e)}async mget(e){return e.length?await this.cmd("MGET",...e):[]}async zadd(e,n,i){await this.cmd("ZADD",e,n,i)}async zrevrange(e,n,i){return await this.cmd("ZREVRANGE",e,n,i)}async zremrangebyscore(e,n){await this.cmd("ZREMRANGEBYSCORE",e,"-inf",n)}async setnx(e,n){await this.cmd("SETNX",e,n)}close(){this.socket?.end()}};function hr(a,e){let n=a.indexOf(`\r
3358
- `,e);if(n<0)return;let i=String.fromCharCode(a[e]),r=a.toString("utf8",e+1,n);switch(i){case"+":return{value:r,end:n+2};case"-":return{value:new Error(r),end:n+2};case":":return{value:Number(r),end:n+2};case"$":{let t=Number(r);return t<0?{value:null,end:n+2}:a.length<n+2+t+2?void 0:{value:a.toString("utf8",n+2,n+2+t),end:n+2+t+2}}case"*":{let t=Number(r);if(t<0)return{value:null,end:n+2};let s=[],o=n+2;for(let l=0;l<t;l++){let c=hr(a,o);if(!c)return;s.push(c.value),o=c.end}return{value:s,end:o}}default:throw new Error(`Unexpected Redis reply type ${JSON.stringify(i)}`)}}var Va=class{constructor(e){this.path=e;try{let n=JSON.parse(yo(e,"utf8"));for(let[i,r]of Object.entries(n.hashes??{}))this.hashes.set(i,new Map(Object.entries(r)));for(let[i,r]of Object.entries(n.strings??{}))this.strings.set(i,r);for(let[i,r]of Object.entries(n.zsets??{}))this.zsets.set(i,new Map(Object.entries(r)))}catch{}}path;hashes=new Map;strings=new Map;zsets=new Map;dirty=!1;hash(e){let n=this.hashes.get(e);return n||this.hashes.set(e,n=new Map),n}async hincrbyfloat(e,n,i){let r=this.hash(e);r.set(n,String(Number(r.get(n)??0)+i)),this.dirty=!0}async hgetall(e){return Object.fromEntries(this.hashes.get(e)??[])}async hset(e,n,i){this.hash(e).set(n,i),this.dirty=!0}async hdel(e,n){this.hashes.get(e)?.delete(n),this.dirty=!0}async setex(e,n,i){this.strings.set(e,{value:i,until:Date.now()+n*1e3}),this.dirty=!0}async get(e){let n=this.strings.get(e);return n?n.until<Date.now()?(this.strings.delete(e),null):n.value:null}async mget(e){return Promise.all(e.map(n=>this.get(n)))}async zadd(e,n,i){let r=this.zsets.get(e);r||this.zsets.set(e,r=new Map),r.set(i,n),this.dirty=!0}async zrevrange(e,n,i){return[...this.zsets.get(e)??[]].sort((t,s)=>s[1]-t[1]).map(([t])=>t).slice(n,i+1)}async zremrangebyscore(e,n){let i=this.zsets.get(e);if(i)for(let[r,t]of i)t<=n&&i.delete(r);for(let[r,t]of this.strings)t.until<Date.now()&&this.strings.delete(r);this.dirty=!0}async setnx(e,n){await this.get(e)||await this.setex(e,10*365*86400,n)}save(){if(!this.dirty)return;this.dirty=!1;let e={hashes:Object.fromEntries([...this.hashes].map(([n,i])=>[n,Object.fromEntries(i)])),strings:Object.fromEntries(this.strings),zsets:Object.fromEntries([...this.zsets].map(([n,i])=>[n,Object.fromEntries(i)]))};wo(`${this.path}.tmp`,JSON.stringify(e)),vo(`${this.path}.tmp`,this.path)}close(){this.save()}};var Rn=class a{constructor(e,n,i){this.kv=e;this.cfg=n;this.deps=i;this.kind=e instanceof Ha?"redis":"file"}kv;cfg;deps;flushed=new Map;dirtyRuns=new Map;timer;busy;kind;static open(e,n){if(e.redisUrl)return new a(new Ha(e.redisUrl),e,n);if(e.file)return new a(new Va(e.file),e,n)}k=e=>`${this.cfg.keyPrefix}${e}`;start(){this.kv.setnx(this.k("since"),new Date().toISOString()).catch(e=>this.error(e)),this.flush(),this.timer=setInterval(()=>{this.flush()},this.cfg.flushSeconds*1e3),this.timer.unref?.()}stop(){this.timer&&clearInterval(this.timer),this.flush().finally(()=>this.kv.close())}markRun(e){this.dirtyRuns.set(e.id,e)}error(e){this.deps.log(JSON.stringify({ts:new Date().toISOString(),level:"error",storage:this.kind,error:String(e?.message??e)}))}flush(){return this.busy?this.busy:(this.busy=this.doFlush().catch(e=>this.error(e)).finally(()=>this.busy=void 0),this.busy)}async doFlush(){let e=this.deps.metrics.snapshot();for(let[t,s]of e){let o=this.flushed.get(t)??Je();for(let l of Object.keys(s)){let c=s[l]-o[l];c&&await this.kv.hincrbyfloat(this.k("metrics"),`${t}\0${l}`,c)}this.flushed.set(t,s)}let n=[...this.dirtyRuns.values()];this.dirtyRuns.clear();let i=this.cfg.runDays*86400;for(let t of n)await this.kv.setex(this.k(`run:${t.id}`),i,JSON.stringify(this.deps.runView(t))),await this.kv.zadd(this.k("runs"),Date.parse(t.lastSeen)||Date.now(),t.id);n.length&&await this.kv.zremrangebyscore(this.k("runs"),Date.now()-i*1e3);let r=await this.kv.hgetall(this.k("guard"));this.deps.guard.replaceSuspended(Object.values(r).map(t=>JSON.parse(t))),this.kv instanceof Va&&this.kv.save()}async totals(){await this.flush();let e=await this.kv.hgetall(this.k("metrics")),n=new Map;for(let[i,r]of Object.entries(e)){let t=i.split("\0"),s=t.pop(),o=t.join("\0"),l=n.get(o)??Je();s in l&&(l[s]=Number(r)),n.set(o,l)}return{rows:n,since:await this.kv.get(this.k("since"))??new Date().toISOString()}}async recentRuns(e){await this.flush();let n=await this.kv.zrevrange(this.k("runs"),0,e-1);return(await this.kv.mget(n.map(r=>this.k(`run:${r}`)))).filter(r=>!!r).map(r=>JSON.parse(r))}async run(e){await this.flush();let n=await this.kv.get(this.k(`run:${e}`));return n?JSON.parse(n):void 0}async suspend(e){for(let n of e)await this.kv.hset(this.k("guard"),[n.app,n.agent,n.fix].join("\0"),JSON.stringify(n))}async resetGuard(e,n){let i=await this.kv.hgetall(this.k("guard")),r=0;for(let[t,s]of Object.entries(i)){let o=JSON.parse(s);(!e||o.app===e)&&(n===void 0||o.agent===n)&&(await this.kv.hdel(this.k("guard"),t),r++)}return await this.flush(),r}};var To=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","host","content-length","accept-encoding"]),Co=["authorization","x-api-key","api-key"],br=new Set(["content-encoding","content-length","transfer-encoding","connection","keep-alive"]),X=class extends Error{constructor(n,i){super(i);this.status=n}status};function ee(a,e){let n=a.headers[e];return Array.isArray(n)?n[0]:n}function fr(a){let e=new URL(a.url??"/","http://gateway");if(/^\/token-lens\/report/.test(e.pathname)&&e.searchParams.get("key"))return e.searchParams.get("key");let n=ee(a,"authorization");return n?.toLowerCase().startsWith("bearer ")?n.slice(7).trim():ee(a,"x-api-key")??ee(a,"api-key")}function kr(a,e){let n=Buffer.from(a),i=Buffer.from(e);return n.length===i.length&&Ao(n,i)}function Pn(a,e){return new Promise((n,i)=>{let r=[],t=0;a.on("data",s=>{t+=s.length,t>e?(i(new X(413,`Request body is larger than ${e} bytes.`)),a.destroy()):r.push(s)}),a.on("end",()=>n(Buffer.concat(r))),a.on("error",i)})}function pe(a,e,n,i={}){let r=JSON.stringify(n,null,2);a.writeHead(e,{"content-type":"application/json",...i}),a.end(r)}function zn(a){try{return JSON.parse(a.toString("utf8"))}catch{return}}var Ro=a=>new RegExp("^"+a.split("*").map(e=>e.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*")+"$","i"),Si=class{constructor(e,n=16*1024*1024){this.sse=e;this.limit=n}sse;limit;usage={};decoder=new TextDecoder;partial="";chunks=[];size=0;body;streamText;push(e){if(this.sse){this.size+e.length<=this.limit?(this.chunks.push(Buffer.from(e)),this.size+=e.length):this.size=1/0;let i=(this.partial+this.decoder.decode(e,{stream:!0})).split(`
3359
- `);this.partial=i.pop()??"";for(let r of i)this.line(r)}else this.size+e.length<=this.limit?(this.chunks.push(Buffer.from(e)),this.size+=e.length):this.size=1/0}line(e){if(!(!e.startsWith("data:")||!e.includes('"usage"')))try{this.usage=Mt(this.usage,la(JSON.parse(e.slice(5))))}catch{}}end(){if(this.sse)this.line(this.partial),this.size!==1/0&&(this.streamText=Buffer.concat(this.chunks).toString("utf8"));else if(this.size!==1/0){this.body=Buffer.concat(this.chunks);try{this.usage=la(JSON.parse(this.body.toString("utf8")))}catch{}}return this.usage}};function yr(a,e={}){let n=e.log??(d=>console.log(d)),i=e.fetch??fetch,r=new _n(a.maxRuns),t=new cn,s=new bn,o=new Map,l=new Set,c=new kn({fetch:(...d)=>i(...d),url:(d,p)=>O(d,p,""),headers:(d,p)=>({...p}),log:n},a.batch),u=new Map,g=new Cn(a.verify.probation),h=Rn.open(a.storage,{metrics:t,guard:g,runView:d=>({...Tn(d),findings:An(d),outputChecks:d.checks,calls:d.calls.slice(-100)}),log:n});h?.start();let E=new Sa(a.embeddingsCacheMB*1024*1024),I=new Map,S=new Map,N=new Set;for(let d of a.models)ai(d);function V(d,p,b){let f=d==="anthropic"||p.startsWith("/v1/messages");if(b){for(let _ of a.routes)if(Ro(_.model).test(b)){let j=a.upstreams[_.upstream];if(f&&j.type!=="anthropic"&&d!=="anthropic")throw new X(400,`Model "${b}" is served by an OpenAI-compatible upstream; call it at /v1/chat/completions.`);if(d&&!f&&j.type!=="openai"&&d!=="openai-chat")throw new X(400,`Model "${b}" is served by an Anthropic upstream; call it at /v1/messages or /v1/chat/completions.`);return[_.upstream,j]}}let A=Object.entries(a.upstreams),G=f?A.find(([,_])=>_.type==="anthropic"):a.defaultUpstream?[a.defaultUpstream,a.upstreams[a.defaultUpstream]]:A.find(([,_])=>_.type==="openai");if(!G)throw new X(502,`No ${f?"Anthropic":"OpenAI-compatible"} upstream is configured for this gateway.`);return G}function O(d,p,b){return d.type==="anthropic"?d.baseUrl.replace(/\/v1$/,"")+p+b:d.baseUrl+p.replace(/^\/v1/,"")+b}function L(d,p){let b={};for(let[f,A]of Object.entries(d.headers))A===void 0||To.has(f)||f.startsWith("x-token-lens-")||Co.includes(f)&&(p.apiKey||a.clientKeys.length)||(b[f]=Array.isArray(A)?A.join(", "):A);if(b["accept-encoding"]="identity",!p.apiKey&&!a.clientKeys.length&&(p.type==="anthropic"&&!b["x-api-key"]&&/^Bearer /i.test(b.authorization??"")?(b["x-api-key"]=b.authorization.replace(/^Bearer /i,""),delete b.authorization):p.type==="openai"&&!b.authorization&&b["x-api-key"]&&!p.authHeader&&(b.authorization=`Bearer ${b["x-api-key"]}`,delete b["x-api-key"],delete b["anthropic-version"])),p.type==="anthropic"&&!b["anthropic-version"]&&(b["anthropic-version"]="2023-06-01"),p.apiKey){let f=p.authHeader??(p.type==="anthropic"?"x-api-key":"authorization");b[f]=f==="authorization"?`Bearer ${p.apiKey}`:p.apiKey,p.type==="anthropic"&&!b["anthropic-version"]&&(b["anthropic-version"]="2023-06-01")}return{...b,...p.headers}}function ae(d){if(!a.clientKeys.length)return(ee(d,"x-token-lens-app")||"default").slice(0,64);let p=fr(d),b=p?a.clientKeys.find(f=>kr(f.key,p)):void 0;return b?b.name:null}let Qe=d=>{let p=fr(d);return!!a.adminKey&&!!p&&kr(a.adminKey,p)};async function Ze(){return h?h.totals():{}}async function da(d){let p=r.list().slice(0,d).map(f=>({...Tn(f),findings:An(f)}));if(!h)return p;let b=(await h.recentRuns(d)).filter(f=>!r.get(f.id));return[...p,...b].sort((f,A)=>String(A.lastSeen).localeCompare(String(f.lastSeen))).slice(0,d)}async function be(d,p,b,f){let A=b.pathname.replace(/\/+$/,""),G=/^\/token-lens\/batches\/(tlb_[0-9a-f]+)$/.exec(A);if(d.method==="GET"&&G){let w=f?c.take(G[1],f):void 0;if(!w)throw new X(404,"No such batch job for this key (results are handed over once, and kept for a day).");return pe(p,200,{id:w.id,object:"token_lens.batch_job",status:w.status,response:w.response,error:w.error})}if(d.method==="GET"&&A==="/metrics"){p.writeHead(200,{"content-type":"text/plain; version=0.0.4"}),p.end(t.prometheus());return}if(d.method==="GET"&&A==="/token-lens/report.csv"){let w=b.searchParams.get("by")==="run"?"run":"agent",v=w==="run"?await da(2e3):t.detail((await Ze()).rows);p.writeHead(200,{"content-type":"text/csv; charset=utf-8","content-disposition":`attachment; filename="token-lens-savings-by-${w}.csv"`,"cache-control":"no-store"}),p.end(nr(v,w));return}if(d.method==="GET"&&(A==="/token-lens/report"||A==="/token-lens/report.json")){let w=await da(50),v=await Ze(),M=t.json(v.rows,v.since);if(A.endsWith(".json"))return pe(p,200,{...M,runs:w,switchedOff:g.list()});p.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),p.end(ar(M,w,g.list()));return}if(d.method==="GET"&&A==="/token-lens/stats"){let w=await Ze();return pe(p,200,{...t.json(w.rows,w.since),calibration:s.snapshot(),switchedOff:g.list(),storage:h?.kind??"memory"})}if(d.method==="GET"&&A==="/token-lens/guard")return pe(p,200,{switchedOff:g.list().filter(w=>Qe(d)||w.app===f)});if(d.method==="POST"&&A==="/token-lens/guard/reset"){if(!Qe(d))throw new X(401,"This endpoint needs the admin key.");let w=JSON.parse((await Pn(d,a.maxBodyBytes)).toString("utf8")||"{}"),[v,M]=[typeof w.app=="string"?w.app:void 0,typeof w.agent=="string"?w.agent:void 0],z=g.reset(v,M);return pe(p,200,{turnedBackOn:h?await h.resetGuard(v,M):z})}if(d.method==="GET"&&A==="/token-lens/runs"){let w=Math.min(500,Number(b.searchParams.get("limit"))||50),v=b.searchParams.get("app"),M=(await da(v?2e3:w)).filter(z=>!v||z.app===v).slice(0,w).map(({findings:z,...$})=>({...$,topFinding:z?.[0]?.title}));return pe(p,200,{runs:M})}let _=/^\/token-lens\/runs\/(.+)$/.exec(A);if(d.method==="GET"&&_){let w=decodeURIComponent(_[1]),v=r.get(w);if(v)return pe(p,200,{...Tn(v),findings:An(v),outputChecks:v.checks,calls:v.calls});let M=await h?.run(w);if(!M)throw new X(404,"No such run (runs are kept in memory, most recent first, or in shared storage when configured).");return pe(p,200,M)}if(d.method==="GET"&&A==="/token-lens/models"){let w=Object.values(te).map(v=>({...v,calibration:s.snapshot()[v.id]}));return pe(p,200,{models:w})}if(d.method==="POST"&&A==="/token-lens/analyze"){let w=JSON.parse((await Pn(d,a.maxBodyBytes)).toString("utf8")||"{}");if(typeof w.prompt!="string"||typeof w.model!="string")throw new X(400,'Send {"prompt": "...", "model": "..."}.');return pe(p,200,Pt({prompt:w.prompt,model:w.model,conversationTokens:w.conversationTokens,level:w.level}))}let j=/^\/token-lens\/models(?:\/(.+))?$/.exec(A);if(j&&(d.method==="POST"||d.method==="DELETE")){if(!a.adminKey)throw new X(403,'Set TOKEN_LENS_ADMIN_KEY to manage models at runtime, or list them under "models" in the config file.');if(!Qe(d))throw new X(401,"This endpoint needs the admin key.");if(d.method==="DELETE"&&j[1])return ni(decodeURIComponent(j[1])),pe(p,200,{deleted:decodeURIComponent(j[1])});let w=JSON.parse((await Pn(d,a.maxBodyBytes)).toString("utf8")||"{}");try{return pe(p,201,{model:ai(w)})}catch(v){throw new X(400,v.message)}}throw new X(404,"Not found.")}function Pe(d,p,b,f){if(d.headersSent){d.end();return}pe(d,b,di(p,b,f))}let ce=d=>d==="anthropic-to-openai"?"/v1/chat/completions":"/v1/messages";function ea(d,p){let b=JSON.parse(p.toString("utf8"));return Buffer.from(JSON.stringify(d==="anthropic-to-openai"?Ut(b):Ht(b)))}function fe(d,p,b){let f=zn(b);return p>=300?Buffer.from(JSON.stringify(Jt(d,f,p))):f?Buffer.from(JSON.stringify(d==="anthropic-to-openai"?Kt(f):$t(f))):b}async function ge(d,p,b,f,A,G,_,j){let w=new AbortController;p.on("close",()=>{p.writableFinished||w.abort()}),j&&A&&(A=ea(j,A));let v=T=>i(O(f,j?ce(j):b.pathname,b.search),{method:d.method,headers:L(d,f),body:T&&T.length&&d.method!=="GET"&&d.method!=="HEAD"?new Uint8Array(T):void 0,signal:w.signal}),M=await v(A);_&&A&&(M=await Ea(M,A,_,T=>v(T)));let z={};M.headers.forEach((T,ne)=>{br.has(ne)||(z[ne]=T)}),Object.assign(z,G);let $=(z["content-type"]??"").includes("event-stream");if(j&&!$){let T=fe(j,M.status,Buffer.from(await M.arrayBuffer()));z["content-type"]="application/json",p.writeHead(M.status,z),p.write(T);let ne=la(zn(T)??{});return{status:M.status,usage:ne,replay:{at:Date.now(),status:M.status,headers:z,body:T,usage:ne}}}p.writeHead(M.status,z);let U=new Si($);if(j&&M.body){let T=new wn(j),ne=new TextDecoder,Me=async he=>{if(!he)return;let Ue=Buffer.from(he);U.push(Ue),p.write(Ue)||await new Promise(D=>p.once("drain",D))};for await(let he of M.body)await Me(T.push(ne.decode(he,{stream:!0})));await Me(T.end())}else if(M.body)for await(let T of M.body)U.push(T),p.write(T)||await new Promise(ne=>p.once("drain",ne));let qe=U.end(),ma=U.body?{at:Date.now(),status:M.status,headers:z,body:U.body,usage:qe}:void 0;return{status:M.status,usage:qe,replay:ma,streamText:U.streamText}}async function Ea(d,p,b,f){if(d.ok||![400,408,422,429].includes(d.status))return d;let A=await d.text();if((d.status===400||d.status===422)&&!/service_tier|flex/i.test(A))return new Response(A,{status:d.status,headers:d.headers});let G=JSON.parse(p.toString("utf8"));return delete G.service_tier,b.fellBack=!0,f(Buffer.from(JSON.stringify(G)))}async function xe(d,p,b,f,A,G){G&&(f=ea(G,f));let _=z=>i(O(b,G?ce(G):p.pathname,p.search),{method:"POST",headers:L(d,b),body:new Uint8Array(z)}),j=await _(f);A&&(j=await Ea(j,f,A,_));let w={};j.headers.forEach((z,$)=>{br.has($)||(w[$]=z)});let v=Buffer.from(await j.arrayBuffer());G&&(v=fe(G,j.status,v),w["content-type"]="application/json");let M=zn(v);return{status:j.status,headers:w,buf:v,json:M,usage:M?la(M):{}}}async function y(d,p,b,f,A,G,_,j){let w=rr(_);if(!w||typeof _.model!="string")return!1;let v=Date.now(),M=Sa.scope(f,A,_),z=w.map(W=>Sa.key(M,W)),$=z.map(W=>E.get(W)),U=w.map((W,ie)=>ie).filter(W=>$[W]===void 0),qe,ma={"content-type":"application/json"};if(U.length){let W=U.length===w.length?j:Buffer.from(JSON.stringify({..._,input:U.map(re=>w[re])})),ie=await xe(d,b,G,W);if(ie.status>=300||!Array.isArray(ie.json?.data)||ie.json.data.length!==U.length)return p.writeHead(ie.status,ie.headers),p.end(ie.buf),!0;for(let re of ie.json.data){let Se=U[re.index];Se!==void 0&&($[Se]=re.embedding,E.set(z[Se],re.embedding))}qe=ie.json,ma=ie.headers}E.hits+=w.length-U.length,E.misses+=U.length;let T=ya(_.model,"generic"),ne=T.id==="generic"?{...T,pricing:void 0}:T,Me=W=>typeof W=="string"?s.count(W,ne):Array.isArray(W)?W.length:0,he=w.reduce((W,ie,re)=>W+(U.includes(re)?0:Me(ie)),0),Ue=qe?.usage??{prompt_tokens:0,total_tokens:0},D={object:"list",data:$.map((W,ie)=>({object:"embedding",index:ie,embedding:W})),model:qe?.model??_.model,usage:Ue};p.writeHead(200,{...ma,"content-type":"application/json","x-token-lens-cached-embeddings":String(w.length-U.length),"x-token-lens-saved-tokens":String(he)}),p.end(JSON.stringify(D));let je=(ee(d,"x-token-lens-agent")||"-").slice(0,100);return t.record({app:f,agent:je,run:"embeddings",profile:ne,status:200,usage:{inputTokens:Ue.prompt_tokens??0},estimatedInput:0,savedInput:he,replayed:!1}),a.logRequests&&n(JSON.stringify({ts:new Date().toISOString(),app:f,model:_.model,upstream:A,embeddings:w.length,cached:w.length-U.length,saved:he,ms:Date.now()-v})),!0}async function x(d,p,b,f){let A=Date.now(),G=b.pathname,_=d.method==="POST"?ui(G):null,j=d.method==="GET"||d.method==="HEAD"?Buffer.alloc(0):await Pn(d,a.maxBodyBytes),w=(ee(d,"content-type")??"application/json").includes("json"),v;if(j.length&&w)try{v=JSON.parse(j.toString("utf8"))}catch{if(_)throw new X(400,"The request body is not valid JSON.")}let[M,z]=V(_,G,typeof v?.model=="string"?v.model:void 0),$=_==="anthropic"&&z.type==="openai"?"anthropic-to-openai":_==="openai-chat"&&z.type==="anthropic"?"openai-to-anthropic":void 0;if(d.method==="POST"&&G==="/v1/embeddings"&&v&&z.type==="openai"&&a.safe.cacheEmbeddings&&a.mode!=="off"&&ee(d,"x-token-lens-mode")!=="off"&&await y(d,p,b,f,M,z,v,j))return;if(!_||!v||typeof v!="object"){await ge(d,p,b,z,j,{}),p.end();return}let U=["optimize","observe","off"].includes(ee(d,"x-token-lens-mode")??"")?ee(d,"x-token-lens-mode"):a.mode;if(U==="off"){await ge(d,p,b,z,j,{},void 0,$),p.end();return}let qe=["light","balanced","aggressive","auto"].includes(ee(d,"x-token-lens-level")??"")?ee(d,"x-token-lens-level"):a.level,ma=new Set((ee(d,"x-token-lens-allow")??"").split(",").map(m=>m.trim()).filter(Boolean)),T=ci(_,v),ne=ya(T.model,z.type==="anthropic"?"claude":"generic"),Me=ne.pricing?gr(a.priceTiers,T.model):void 0,he=ne.pricing?.longContext,Ue=Me?{aboveInputTokens:Me.aboveInputTokens,inputPerMTok:Me.inputPerMTok,outputPerMTok:Me.outputPerMTok}:he?{aboveInputTokens:he.aboveTokens,inputPerMTok:he.inputPerMTok,outputPerMTok:he.outputPerMTok}:void 0,D=Ue?{...ne,priceTier:Ue}:ne,je=hn(T.refs),W=ee(d,"x-token-lens-run")?.slice(0,200),ie=T.refs.find(m=>m.user)?.get()??"",re=W?`${f}:${W}`:Ua(f,D.id,je.system.join(`
3360
- `),ie),Se=(ee(d,"x-token-lens-agent")||"-").slice(0,100),F=r.open(re,f,!!W,Se),In=Ua(M,G,j.toString("utf8")),wr=F.requestHashes.has(In);F.requestHashes.size<5e3&&F.requestHashes.add(In);let xn=Ua(je.system.join(`
3361
- `),je.tools.join(`
3362
- `)),Mn=F.prefixes.get(xn)??0;F.prefixes.set(xn,Mn+1);let Sr=(Array.isArray(v.tools)?v.tools:[]).map(m=>m?.function?.name??m?.name??"").filter(Boolean),Ei=cr(je.system.join(`
3363
- `),je.tools,Sr),Wa=ur(F.prefixPrint,Ei,je.system.join(`
3364
- `),je.tools.join(`
3365
- `));F.prefixPrint=Ei;let Ai=dr(_,v),_r=mr(_,v),Ka=pr(T.toolCalls);if(Ka.length){let m=I.get(f);m||I.set(f,m=new Map);for(let C of Ka){let R=m.get(C);R||(m.size>=2e4&&m.delete(m.keys().next().value),m.set(C,R=new Set)),R.size<50&&R.add(re)}let k=new Set,P=0;for(let C of Ka){let R=m.get(C);if(R.size>1){P++;for(let q of R)q!==re&&k.add(q)}}F.sharedReads=P?{files:P,of:Ka.length,runs:k.size,agents:[...new Set([...k].map(C=>r.get(C)?.agent??"-"))].slice(0,5)}:void 0}let Ti=m=>a.reportToolArgs?m:`input #${Ua(m).slice(0,8)}`,jn=new Map;for(let m of T.toolCalls){let k=`${m.name}\0${m.args}`,P=jn.get(k)??{name:m.name,args:Ti(m.args),count:0};P.count++,jn.set(k,P)}let Er=[...jn.values()].filter(m=>m.count>1),Ci,Aa=T.toolCalls.at(-1);if(Aa){let m=0;for(let k=T.toolCalls.length-1;k>=0&&T.toolCalls[k].name===Aa.name&&T.toolCalls[k].args===Aa.args;k--)m++;m>1&&(Ci={name:Aa.name,args:Ti(Aa.args),times:m})}let _e=fn(T.refs,D,s),On=_e.parts.system+_e.parts.tools,$a={"x-token-lens-run":re,"x-token-lens-profile":D.id},Ar=()=>{let m=z.type==="anthropic"?"anthropic":"openai",k=mn(_,v);if(!k.length)return;let P=Math.max(...k.map(R=>R.turn)),C=R=>ti(m,R)??0;return{count:k.length,tokens:k.reduce((R,q)=>R+C(q),0),oldTokens:k.filter(R=>R.turn<P-1).reduce((R,q)=>R+C(q),0),provider:m}},Ta=(m,k,P,C,R={},q=1)=>{let ke={images:Ar(),at:new Date().toISOString(),model:T.model,profile:D.id,upstream:M,status:m,parts:P.parts,input:P.total,toolOutputs:P.toolOutputs,usage:k,actions:C,duplicate:wr,window:D.contextWindow,ms:Date.now()-A,costUsd:R.replayed||m>=400?0:oa(D,{...k,inputTokens:k.inputTokens??P.total})*q,costBeforeUsd:ln(D,{...k,inputTokens:k.inputTokens??P.total},C.reduce((Te,na)=>Te+na.saved,0)),toolCalls:T.toolCalls.length,repeatedToolCalls:Er,sameCallStreak:Ci,api:_,...Wa&&On>=1024?{cacheBreak:{kind:Wa.kind,where:Wa.where,tokens:Math.round(Wa.lostShare*On)}}:{},...Ai?{jsonRetries:Ai,structuredOutput:_r}:{},...D.priceTier?{priceTier:D.priceTier}:{},...q!==1?{priceFactor:q}:{},...R};r.record(F,ke),h?.markRun(F);let pa=C.reduce((Te,na)=>Te+na.saved,0);t.record({app:f,agent:F.agent,run:re,profile:D,status:m,usage:k,estimatedInput:P.total,savedInput:pa,replayed:!!R.replayed,priceFactor:q}),a.logRequests&&n(JSON.stringify({ts:ke.at,app:f,run:re,model:T.model,profile:D.id,upstream:M,status:m,input:k.inputTokens??P.total,output:k.outputTokens,cached:k.cachedInputTokens,saved:pa,actions:C.map(Te=>Te.id),replayed:R.replayed||void 0,ms:ke.ms}))},Ri=`${f}\0${In}`,Pi=a.safe.dedupeRetries&&U==="optimize"&&!T.stream&&T.temperature===0,aa=Pi?o.get(Ri):void 0;if(aa&&Date.now()-aa.at<=a.retryWindowSeconds*1e3){p.writeHead(aa.status,{...aa.headers,...$a,"x-token-lens-replayed":"true"}),Ta(aa.status,aa.usage,_e,[],{replayed:!0}),p.end(aa.body);return}let Ja=Number(ee(d,"x-token-lens-max-calls"))||a.runBudget.maxCalls,Ya=Number(ee(d,"x-token-lens-max-cost-usd"))||a.runBudget.maxCostUsd,Dn=F.calls.filter(m=>!m.replayed&&!m.overBudget&&m.status<400),zi=Dn.reduce((m,k)=>m+k.costUsd,0);if(Ja&&Dn.length>=Ja||Ya&&zi>=Ya){let m=`Token Lens stopped this run: it reached its budget (${Dn.length} calls, $${zi.toFixed(4)} spent; limit ${[Ja?`${Ja} calls`:"",Ya?`$${Ya}`:""].filter(Boolean).join(" / ")}). Start a new run or raise the limit.`;p.writeHead(429,{"content-type":"application/json",...$a,"x-token-lens-budget":"exceeded"}),p.end(JSON.stringify(di(_,429,m))),Ta(429,{},_e,[],{overBudget:!0});return}let Ii=ee(d,"x-token-lens-batch"),Xa=Ii==="true"||Ii==="1",Ee=g.configFor(a,f,Se,ma,!!T.stream||Xa),xi=Ee.cfg.optIn.warmCache||(Ee.allow.has("warm-cache")?{maxWaitMs:15e3}:!1),Qa,Za;if(xi&&U==="optimize"&&!Xa&&On>=1024&&Ee.cfg.safe.promptCaching){let m=[f,M,T.model,xn].join("\0"),k=S.get(m);if(k){let P=Date.now(),C;await Promise.race([k,new Promise(R=>C=setTimeout(R,xi.maxWaitMs))]),clearTimeout(C),Qa=Date.now()-P}else if(!N.has(m)){let P;S.set(m,new Promise(C=>P=C)),Za=()=>{S.has(m)&&(S.delete(m),N.add(m),N.size>5e3&&N.delete(N.values().next().value),P())},p.on("close",Za)}}let J={actions:[],tips:[]},Q=_e;if(U==="optimize"){let m={cfg:Ee.cfg,body:v,parsed:T,profile:D,upstream:z,counter:s,prefixRepeats:Za?Math.max(Mn,1):Mn,runId:re,level:qe,allow:Ee.allow,conversationTokens:_e.total-_e.parts.prompt-_e.parts.context};J=jt(m),J.actions.length&&(Q=fn(T.refs,D,s));let k=Ot(m,Q);k&&J.actions.push(k),Qa!==void 0&&J.actions.push({id:"warm-cache",saved:0})}let Tr=Ee.cfg.optIn.flex||Ee.allow.has("flex"),Cr=z.flex??(z.type==="openai"&&/(^|\.)api\.openai\.com$/.test(new URL(z.baseUrl).hostname)),He=Tr&&Cr&&_!=="anthropic"&&!Xa&&v.service_tier===void 0?{fellBack:!1}:void 0;if(He&&(v.service_tier="flex",J.actions.push({id:"flex",saved:0})),a.blockOverContext&&Q.total+(T.maxOutputTokens??0)>D.contextWindow){let m=`This request needs about ${Q.total+(T.maxOutputTokens??0)} tokens but ${D.label} has a ${D.contextWindow}-token context window. Rejected by Token Lens before it was sent.`;Pe(p,_,400,m),Ta(400,{},Q,J.actions);return}if(Xa){if(T.stream)return Pe(p,_,400,"Requests sent with x-token-lens-batch can't stream.");let m=c.canBatch(_,G,z);if(m)return Pe(p,_,400,m);let k=L(d,z);for(let R of["content-length","host","accept-encoding"])delete k[R];let P=[...J.actions,{id:"batch",saved:0}],C=c.add({app:f,protocol:_,path:G,upstream:M,body:v,onDone:(R,q)=>Ta(q?200:502,R,Q,P,{},q?a.batch.discount:1)},z,k);p.writeHead(202,{"content-type":"application/json",...$a,"x-token-lens-batch-id":C.id}),p.end(JSON.stringify({id:C.id,object:"token_lens.batch_job",status:C.status,result_url:`/token-lens/batches/${C.id}`}));return}let Mi=yi({...F,calls:[...F.calls,{parts:Q.parts,status:200}]}),Rr=J.actions.reduce((m,k)=>m+k.saved,0),ue={...$a,"x-token-lens-input-tokens":String(Q.total),"x-token-lens-saved-tokens":String(Rr)};J.actions.length&&(ue["x-token-lens-actions"]=J.actions.map(m=>m.id).join(","));let ji=J.tips.filter(m=>m.id!=="lighter-model");ji.length&&(ue["x-token-lens-tips"]=ji.map(m=>m.id).join(",")),Mi&&(ue["x-token-lens-growing"]=Mi),Qa!==void 0&&(ue["x-token-lens-warm-wait-ms"]=String(Qa)),D.priceTier&&Q.total>.9*D.priceTier.aboveInputTokens&&(ue["x-token-lens-price-tier"]=`${Q.total>D.priceTier.aboveInputTokens?"above":"near"} ${D.priceTier.aboveInputTokens}`);let Oi=Ee.cfg.optIn.lazyTools||(Ee.allow.has("lazy-tools")?{minTools:8}:!1),Ae=U==="optimize"&&Oi?Bt(_,v,Oi.minTools):null,Nn=Ee.cfg.optIn.parkToolOutputs||(Ee.allow.has("park-tool-outputs")?{minTokens:1500,keepLast:1}:!1),Pr=Ae||Nn?structuredClone(v):void 0,Ve=U==="optimize"&&Nn&&!T.stream&&(_==="openai-chat"||_==="anthropic")&&v.tool_choice!=="none"?Xt(T,Nn,s,D,F.parked??=new Map):[];if(F.parked&&F.parked.size>50)for(let m of[...F.parked.keys()].slice(0,F.parked.size-50))F.parked.delete(m);let Di=g.onProbation(f,Se,[...J.actions.map(m=>m.id),...Ae?["lazy-tools"]:[],...Ve.length?["park-tool-outputs"]:[]]),Ln=Di.length?xe(d,b,z,j,void 0,$).catch(()=>{}):void 0,Y;if(Ae||Ve.length){let m=F.loadedTools??=new Set;for(let de of T.toolCalls)m.add(de.name);let k={},P=0,C=0,R,q=!1;for(;C<4&&!R;C++){let de=Ae?Ft(_,v,Ae,m):[];Ve.length&&!(v.tools??=[]).some(We=>(We?.function?.name??We?.name)===Fe)&&v.tools.push(Yt(_));let ye=await xe(d,b,z,Buffer.from(JSON.stringify(v)),He,$);if(k=bi(k,ye.usage),ye.status>=300){R=ye;break}let Gn=Zt(_,ye.json),Hi=Ve.length?Gn.filter(We=>We.name===Fe):[],qn=de.length?Gt(_,ye.json,de):[];if(!Hi.length&&!qn.length){R=ye;break}P+=ye.usage.inputTokens??0;for(let We of qn)m.add(We);if(Hi.length){if(Gn.some(ga=>ga.name!==Fe&&ga.name!==ca))break;let We=new Map(Gn.map(ga=>[ga.id,ga.name===Fe?Qt(F.parked,ga.args):`Loaded: ${qn.join(", ")||"none"}. Their full definitions are now in the tool list.`]));er(_,v,ye.json,We)}}R||(q=!0,Object.keys(v).forEach(de=>delete v[de]),Object.assign(v,Pr,Ae?{tools:Ae.original}:{}),R=await xe(d,b,z,Buffer.from(JSON.stringify(v)),He,$),k=bi(k,R.usage));let ke=fn(ci(_,v).refs,D,s),pa=Q.total-ke.total-P,Te=Ae&&!q?Math.max(0,Q.parts.tools-ke.parts.tools):0,na=Ve.length&&!q?Math.max(0,pa+P-Te):0,Ui=(de,ye)=>Te+na?Math.round(pa*de/(Te+na)):ye?Math.round(pa/((Ae?1:0)+(Ve.length?1:0))):0;Ae&&(Te||C>1||q)&&J.actions.push({id:"lazy-tools",saved:Ui(Te,!0),count:C-1}),Ve.length&&J.actions.push({id:"park-tool-outputs",saved:Ui(na,!0),count:Ve.length});for(let de of Ie(_,R.json).toolCalls)m.add(de.name);Q={...ke,total:ke.total},ue["x-token-lens-input-tokens"]=String(Q.total),ue["x-token-lens-saved-tokens"]=String(J.actions.reduce((de,ye)=>de+ye.saved,0)),ue["x-token-lens-actions"]=J.actions.map(de=>de.id).join(","),Y={...R,usage:k}}else Ln&&(Y=await xe(d,b,z,Buffer.from(JSON.stringify(v)),He,$));let en,Bn=!1;if(Y&&Ln){let m=await Ln,k=Di.filter(P=>J.actions.some(C=>C.id===P));if(m&&m.status<300&&k.length){let P=Ie(_,m.json),C=vn(Ie(_,Y.json),P,J.actions.reduce((R,q)=>R+q.saved,0),a.verify.minSimilarity);Y.status<300&&C.match?(g.confirm(f,Se,k),en={check:C,ids:k,originalOutput:P,costUsd:oa(D,m.usage),tokens:(m.usage.inputTokens??0)+(m.usage.outputTokens??0)}):(en={check:{...C,match:!1},ids:k,originalOutput:P,costUsd:oa(D,Y.usage),tokens:(Y.usage.inputTokens??0)+(Y.usage.outputTokens??0)},Y=m,Bn=!0,Q=_e,ue["x-token-lens-input-tokens"]=String(_e.total),ue["x-token-lens-saved-tokens"]="0",ue["x-token-lens-answer"]="original",delete ue["x-token-lens-actions"])}}let oe;if(Y)p.writeHead(Y.status,{...Y.headers,...ue}),p.write(Y.buf),oe={status:Y.status,usage:Y.usage,replay:{at:Date.now(),status:Y.status,headers:Y.headers,body:Y.buf,usage:Y.usage}};else{let m=J.actions.length?Buffer.from(JSON.stringify(v)):j;oe=await ge(d,p,b,z,m,ue,He,$)}oe.usage.inputTokens&&!Ae&&!Bn&&s.observe(D,Q.raw,oe.usage.inputTokens),Pi&&oe.replay&&oe.status<300&&(o.set(Ri,oe.replay),o.size>500&&o.delete(o.keys().next().value));let an=Bn?[]:J.actions.filter(m=>m.id!=="flex"||!He?.fellBack);Ta(oe.status,oe.usage,Q,an,{},He&&!He.fellBack&&oe.status<300?a.flexDiscount:1),Za?.(),p.end();let Ni=`${f}\0${F.agent}`,ze=u.get(Ni)??{checks:0,checkTokens:0,saved:0};u.set(Ni,ze);let Fn=an.reduce((m,k)=>m+k.saved,0);ze.saved+=Fn;let Li=()=>{if(!T.stream)return j;let{stream:m,stream_options:k,...P}=JSON.parse(j.toString("utf8"));return Buffer.from(JSON.stringify(P))},Bi=(m,k,P)=>{let C={...m,actions:k,costUsd:P};return F.checks.push(C),h?.markRun(F),F.checks.length>200&&F.checks.shift(),t.recordCheck(f,F.agent,D,m.match,P),a.logRequests&&n(JSON.stringify({ts:m.at,app:f,run:re,outputCheck:m.match?"same":"different",similarity:m.similarity,sameToolCalls:m.sameToolCalls})),C},Fi=async(m,k,P)=>{let C=await xe(d,b,z,Li(),void 0,$);if(C.status<300&&(ze.checkTokens+=(C.usage.inputTokens??_e.total)+(C.usage.outputTokens??0),t.recordCheck(f,F.agent,D,!0,oa(D,C.usage),!1),!vn(Ie(_,C.json),k,0,a.verify.minSimilarity).match)){m.modelVaries=!0;return}let R=g.suspend(f,Se,P,m);h&&R.length&&await h.suspend(g.list().filter(q=>q.app===f&&q.agent===Se&&R.includes(q.fix))),R.length&&n(JSON.stringify({ts:new Date().toISOString(),level:"warn",app:f,agent:Se,switchedOff:R,reason:"an output check found a different answer"}))},Gi=m=>{let k=m().catch(P=>n(JSON.stringify({ts:new Date().toISOString(),level:"error",outputCheck:String(P?.message??P)})));l.add(k),k.finally(()=>l.delete(k))};if(en){let m=en;ze.checks++,ze.checkTokens+=m.tokens;let k=Bi(m.check,m.ids,m.costUsd);m.check.match||Gi(()=>Fi(k,m.originalOutput,m.ids));return}let zr=an.some(m=>wa.has(m.id))&&a.verify.sampleRate>0?Math.max(a.verify.sampleRate,.25):a.verify.sampleRate,Ir=ee(d,"x-token-lens-verify")==="1",xr=ze.checks<a.verify.freeChecks||ze.checkTokens<ze.saved*a.verify.maxShareOfSavings,qi=T.stream?oe.streamText!==void 0?Nt(_,oe.streamText):void 0:oe.replay?Ie(_,zn(oe.replay.body)):void 0;Fn>0&&oe.status<300&&qi&&(Ir||xr&&Math.random()<zr)&&(ze.checks++,Gi(async()=>{let m=await xe(d,b,z,Li(),void 0,$);if(m.status>=300)return;let k=m.usage;ze.checkTokens+=(k.inputTokens??Q.total)+(k.outputTokens??0);let P=Ie(_,m.json),C=vn(qi,P,Fn,a.verify.minSimilarity),R=an.filter(ke=>ke.saved>0).map(ke=>ke.id),q=Bi(C,R,oa(D,k));C.match||await Fi(q,P,R)}))}let K=Eo(async(d,p)=>{let b=new URL(d.url??"/","http://gateway"),f=ui(b.pathname);try{if(d.method==="GET"&&(b.pathname==="/healthz"||b.pathname==="/"))return pe(p,200,{ok:!0,service:"token-lens-gateway",upstreams:Object.keys(a.upstreams),mode:a.mode});let A=ae(d);if(b.pathname==="/metrics"||b.pathname.startsWith("/token-lens/")){let G=/^\/token-lens\/models/.test(b.pathname)&&d.method!=="GET";if(!A&&!Qe(d)&&!G)throw new X(401,"Missing or unknown Token Lens key.");return await be(d,p,b,A)}if(!b.pathname.startsWith("/v1/"))throw new X(404,"Not found. Point your SDK's base URL at this gateway (OpenAI: <gateway>/v1, Anthropic: <gateway>).");if(!A)throw new X(401,"Missing or unknown Token Lens key.");await x(d,p,b,A)}catch(A){if(A instanceof X)return Pe(p,f,A.status,A.message);if(A.name==="AbortError")return;n(JSON.stringify({ts:new Date().toISOString(),level:"error",path:b.pathname,error:String(A.message??A)})),Pe(p,f,502,`Upstream request failed: ${A.message}`)}});return K.on("close",()=>{c.stop(),h?.stop()}),{server:K,cfg:a,runs:r,metrics:t,counter:s,batches:c,guard:g,storage:h,settle:()=>Promise.all([...l]).then(()=>{})}}var Xe=Vi(),{server:vr}=yr(Xe),_i=Object.entries(Xe.upstreams);_i.length||console.warn("token-lens: no upstreams configured. Set OPENAI_API_KEY / ANTHROPIC_API_KEY or TOKEN_LENS_CONFIG.");!Xe.clientKeys.length&&_i.some(([,a])=>a.apiKey)&&console.warn("token-lens: no client keys set, so anyone who can reach this port can use the upstream keys. Set TOKEN_LENS_CLIENT_KEYS unless the network is private.");vr.listen(Xe.port,Xe.host,()=>{console.log(`token-lens gateway on http://${Xe.host}:${Xe.port} (mode: ${Xe.mode}; upstreams: ${_i.map(([a,e])=>`${a}=${e.type}`).join(", ")||"none"})`)});for(let a of["SIGINT","SIGTERM"])process.on(a,()=>{vr.close(()=>process.exit(0)),setTimeout(()=>process.exit(0),5e3).unref()});
3360
+ `)])]))})}async cmd(...e){await this.connect();let n=await this.raw(e);if(n instanceof Error)throw n;return n}data(e){for(this.buf=Buffer.concat([this.buf,e]);;){let n=Fr(this.buf,0);if(!n)return;this.buf=this.buf.subarray(n.end),this.waiting.shift()?.resolve(n.value)}}async hincrbyfloat(e,n,i){await this.cmd("HINCRBYFLOAT",e,n,i)}async hgetall(e){let n=await this.cmd("HGETALL",e),i={};for(let r=0;r+1<n.length;r+=2)i[n[r]]=n[r+1];return i}async hset(e,n,i){await this.cmd("HSET",e,n,i)}async hdel(e,n){await this.cmd("HDEL",e,n)}async setex(e,n,i){await this.cmd("SET",e,i,"EX",Math.max(1,Math.round(n)))}async get(e){return await this.cmd("GET",e)}async mget(e){return e.length?await this.cmd("MGET",...e):[]}async zadd(e,n,i){await this.cmd("ZADD",e,n,i)}async zrevrange(e,n,i){return await this.cmd("ZREVRANGE",e,n,i)}async zremrangebyscore(e,n){await this.cmd("ZREMRANGEBYSCORE",e,"-inf",n)}async setnx(e,n){await this.cmd("SETNX",e,n)}async expire(e,n){await this.cmd("EXPIRE",e,Math.max(1,Math.round(n)))}close(){this.socket?.end()}};function Fr(a,e){let n=a.indexOf(`\r
3361
+ `,e);if(n<0)return;let i=String.fromCharCode(a[e]),r=a.toString("utf8",e+1,n);switch(i){case"+":return{value:r,end:n+2};case"-":return{value:new Error(r),end:n+2};case":":return{value:Number(r),end:n+2};case"$":{let t=Number(r);return t<0?{value:null,end:n+2}:a.length<n+2+t+2?void 0:{value:a.toString("utf8",n+2,n+2+t),end:n+2+t+2}}case"*":{let t=Number(r);if(t<0)return{value:null,end:n+2};let s=[],o=n+2;for(let l=0;l<t;l++){let c=Fr(a,o);if(!c)return;s.push(c.value),o=c.end}return{value:s,end:o}}default:throw new Error(`Unexpected Redis reply type ${JSON.stringify(i)}`)}}var en=class{constructor(e){this.path=e;try{let n=JSON.parse(Jo(e,"utf8"));for(let[i,r]of Object.entries(n.hashes??{}))this.hashes.set(i,new Map(Object.entries(r)));for(let[i,r]of Object.entries(n.strings??{}))this.strings.set(i,r);for(let[i,r]of Object.entries(n.zsets??{}))this.zsets.set(i,new Map(Object.entries(r)));for(let[i,r]of Object.entries(n.expiries??{}))this.expiries.set(i,Number(r))}catch{}}path;hashes=new Map;strings=new Map;zsets=new Map;expiries=new Map;dirty=!1;hash(e){this.dropExpired(e);let n=this.hashes.get(e);return n||this.hashes.set(e,n=new Map),n}async hincrbyfloat(e,n,i){let r=this.hash(e);r.set(n,String(Number(r.get(n)??0)+i)),this.dirty=!0}async hgetall(e){return this.dropExpired(e),Object.fromEntries(this.hashes.get(e)??[])}dropExpired(e){let n=this.expiries.get(e);n!==void 0&&n<Date.now()&&(this.hashes.delete(e),this.expiries.delete(e),this.dirty=!0)}async expire(e,n){this.expiries.set(e,Date.now()+n*1e3),this.dirty=!0}async hset(e,n,i){this.hash(e).set(n,i),this.dirty=!0}async hdel(e,n){this.hashes.get(e)?.delete(n),this.dirty=!0}async setex(e,n,i){this.strings.set(e,{value:i,until:Date.now()+n*1e3}),this.dirty=!0}async get(e){let n=this.strings.get(e);return n?n.until<Date.now()?(this.strings.delete(e),null):n.value:null}async mget(e){return Promise.all(e.map(n=>this.get(n)))}async zadd(e,n,i){let r=this.zsets.get(e);r||this.zsets.set(e,r=new Map),r.set(i,n),this.dirty=!0}async zrevrange(e,n,i){return[...this.zsets.get(e)??[]].sort((t,s)=>s[1]-t[1]).map(([t])=>t).slice(n,i+1)}async zremrangebyscore(e,n){let i=this.zsets.get(e);if(i)for(let[r,t]of i)t<=n&&i.delete(r);for(let[r,t]of this.strings)t.until<Date.now()&&this.strings.delete(r);this.dirty=!0}async setnx(e,n){await this.get(e)||await this.setex(e,10*365*86400,n)}save(){for(let n of[...this.expiries.keys()])this.dropExpired(n);if(!this.dirty)return;this.dirty=!1;let e={hashes:Object.fromEntries([...this.hashes].map(([n,i])=>[n,Object.fromEntries(i)])),strings:Object.fromEntries(this.strings),zsets:Object.fromEntries([...this.zsets].map(([n,i])=>[n,Object.fromEntries(i)])),expiries:Object.fromEntries(this.expiries)};Xo(`${this.path}.tmp`,JSON.stringify(e)),Yo(`${this.path}.tmp`,this.path)}close(){this.save()}};var Gn=class a{constructor(e,n,i){this.kv=e;this.cfg=n;this.deps=i;this.kind=e instanceof Za?"redis":"file"}kv;cfg;deps;flushed=new Map;flushedCustomers=new Map;dirtyRuns=new Map;timer;busy;kind;static open(e,n){if(e.redisUrl)return new a(new Za(e.redisUrl),e,n);if(e.file)return new a(new en(e.file),e,n)}k=e=>`${this.cfg.keyPrefix}${e}`;start(){this.kv.setnx(this.k("since"),new Date().toISOString()).catch(e=>this.error(e)),this.flush(),this.timer=setInterval(()=>{this.flush()},this.cfg.flushSeconds*1e3),this.timer.unref?.()}stop(){this.timer&&clearInterval(this.timer),this.flush().finally(()=>this.kv.close())}markRun(e){this.dirtyRuns.set(e.id,e)}error(e){this.deps.log(JSON.stringify({ts:new Date().toISOString(),level:"error",storage:this.kind,error:String(e?.message??e)}))}flush(){return this.busy?this.busy:(this.busy=this.doFlush().catch(e=>this.error(e)).finally(()=>this.busy=void 0),this.busy)}async doFlush(){let e=this.deps.metrics.snapshot();for(let[s,o]of e){let l=this.flushed.get(s)??fe();for(let c of Object.keys(o)){let u=o[c]-l[c];u&&await this.kv.hincrbyfloat(this.k("metrics"),`${s}\0${c}`,u)}this.flushed.set(s,o)}let n=this.deps.ledger;if(n){let s=n.snapshot();for(let l of this.flushedCustomers.keys())s.has(l)||this.flushedCustomers.delete(l);for(let[l,c]of s){let u=this.flushedCustomers.get(l)??fe();for(let g of Object.keys(c)){let h=c[g]-u[g];h&&await this.kv.hincrbyfloat(this.k("customers"),`${l}\0${g}`,h)}this.flushedCustomers.set(l,c)}let o=new Set;for(let{period:l,field:c,by:u}of n.takeSpendDeltas())await this.kv.hincrbyfloat(this.k(`spend:${l}`),c,u),o.add(l);for(let l of o)await this.kv.expire(this.k(`spend:${l}`),ut(l.startsWith("d")?"day":"month"));for(let l of n.currentPeriods())n.setSharedSpend(l,await this.kv.hgetall(this.k(`spend:${l}`)))}let i=[...this.dirtyRuns.values()];this.dirtyRuns.clear();let r=this.cfg.runDays*86400;for(let s of i)await this.kv.setex(this.k(`run:${s.id}`),r,JSON.stringify(this.deps.runView(s))),await this.kv.zadd(this.k("runs"),Date.parse(s.lastSeen)||Date.now(),s.id);i.length&&await this.kv.zremrangebyscore(this.k("runs"),Date.now()-r*1e3);let t=await this.kv.hgetall(this.k("guard"));this.deps.guard.replaceSuspended(Object.values(t).map(s=>JSON.parse(s))),this.kv instanceof en&&this.kv.save()}async totals(){await this.flush();let e=await this.kv.hgetall(this.k("metrics")),n=new Map;for(let[i,r]of Object.entries(e)){let t=i.split("\0"),s=t.pop(),o=t.join("\0"),l=n.get(o)??fe();s in l&&(l[s]=Number(r)),n.set(o,l)}return{rows:n,since:await this.kv.get(this.k("since"))??new Date().toISOString()}}async customerTotals(){await this.flush();let e=await this.kv.hgetall(this.k("customers")),n=new Map;for(let[i,r]of Object.entries(e)){let t=i.split("\0"),s=t.pop(),o=t.join("\0"),l=n.get(o)??fe();s in l&&(l[s]=Number(r)),n.set(o,l)}return n}async recentRuns(e){await this.flush();let n=await this.kv.zrevrange(this.k("runs"),0,e-1);return(await this.kv.mget(n.map(r=>this.k(`run:${r}`)))).filter(r=>!!r).map(r=>JSON.parse(r))}async run(e){await this.flush();let n=await this.kv.get(this.k(`run:${e}`));return n?JSON.parse(n):void 0}async suspend(e){for(let n of e)await this.kv.hset(this.k("guard"),[n.app,n.agent,n.fix].join("\0"),JSON.stringify(n))}async resetGuard(e,n){let i=await this.kv.hgetall(this.k("guard")),r=0;for(let[t,s]of Object.entries(i)){let o=JSON.parse(s);(!e||o.app===e)&&(n===void 0||o.agent===n)&&(await this.kv.hdel(this.k("guard"),t),r++)}return await this.flush(),r}};var nl=new Set(["connection","keep-alive","proxy-authenticate","proxy-authorization","te","trailer","transfer-encoding","upgrade","host","content-length","accept-encoding"]),il=["authorization","x-api-key","api-key"],Gr=new Set(["content-encoding","content-length","transfer-encoding","connection","keep-alive"]),$=class extends Error{constructor(n,i){super(i);this.status=n}status};function Q(a,e){let n=a.headers[e];return Array.isArray(n)?n[0]:n}function qr(a){let e=new URL(a.url??"/","http://gateway");if(/^\/token-lens\/report/.test(e.pathname)&&e.searchParams.get("key"))return e.searchParams.get("key");let n=Q(a,"authorization");return n?.toLowerCase().startsWith("bearer ")?n.slice(7).trim():Q(a,"x-api-key")??Q(a,"api-key")}function Ur(a,e){let n=Buffer.from(a),i=Buffer.from(e);return n.length===i.length&&al(n,i)}function qn(a,e){return new Promise((n,i)=>{let r=[],t=0;a.on("data",s=>{t+=s.length,t>e?(i(new $(413,`Request body is larger than ${e} bytes.`)),a.destroy()):r.push(s)}),a.on("end",()=>n(Buffer.concat(r))),a.on("error",i)})}function le(a,e,n,i={}){let r=JSON.stringify(n,null,2);a.writeHead(e,{"content-type":"application/json",...i}),a.end(r)}function Un(a){try{return JSON.parse(a.toString("utf8"))}catch{return}}var tl=a=>new RegExp("^"+a.split("*").map(e=>e.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*")+"$","i"),Ni=class{constructor(e,n=16*1024*1024){this.sse=e;this.limit=n}sse;limit;usage={};decoder=new TextDecoder;partial="";chunks=[];size=0;body;streamText;push(e){if(this.sse){this.size+e.length<=this.limit?(this.chunks.push(Buffer.from(e)),this.size+=e.length):this.size=1/0;let i=(this.partial+this.decoder.decode(e,{stream:!0})).split(`
3362
+ `);this.partial=i.pop()??"";for(let r of i)this.line(r)}else this.size+e.length<=this.limit?(this.chunks.push(Buffer.from(e)),this.size+=e.length):this.size=1/0}line(e){if(!(!e.startsWith("data:")||!e.includes('"usage"')))try{this.usage=tr(this.usage,ha(JSON.parse(e.slice(5))))}catch{}}end(){if(this.sse)this.line(this.partial),this.size!==1/0&&(this.streamText=Buffer.concat(this.chunks).toString("utf8"));else if(this.size!==1/0){this.body=Buffer.concat(this.chunks);try{this.usage=ha(JSON.parse(this.body.toString("utf8")))}catch{}}return this.usage}};function Hr(a,e={}){let n=e.log??(d=>console.log(d)),i=e.fetch??fetch,r=new Dn(a.maxRuns),t=new gn,s=new kn(a.customers.maxCustomers),o=new zn,l=new Map,c=new Set,u=new xn({fetch:(...d)=>i(...d),url:(d,p)=>F(d,p,""),headers:(d,p)=>({...p}),log:n},a.batch),g=new Map,h=new Fn(a.verify.probation),y=Gn.open(a.storage,{metrics:t,ledger:s,guard:h,runView:d=>({...Bn(d),findings:Ln(d),outputChecks:d.checks,calls:d.calls.slice(-100)}),log:n});y?.start();let I=new Ia(a.embeddingsCacheMB*1024*1024),E=new Map,H=new Map,W=new Set;for(let d of a.models)ki(d);function L(d,p,f){let b=d==="anthropic"||p.startsWith("/v1/messages");if(f){for(let A of a.routes)if(tl(A.model).test(f)){let O=a.upstreams[A.upstream];if(b&&O.type!=="anthropic"&&d!=="anthropic")throw new $(400,`Model "${f}" is served by an OpenAI-compatible upstream; call it at /v1/chat/completions.`);if(d&&!b&&O.type!=="openai"&&d!=="openai-chat")throw new $(400,`Model "${f}" is served by an Anthropic upstream; call it at /v1/messages or /v1/chat/completions.`);return[A.upstream,O]}}let x=Object.entries(a.upstreams),P=b?x.find(([,A])=>A.type==="anthropic"):a.defaultUpstream?[a.defaultUpstream,a.upstreams[a.defaultUpstream]]:x.find(([,A])=>A.type==="openai");if(!P)throw new $(502,`No ${b?"Anthropic":"OpenAI-compatible"} upstream is configured for this gateway.`);return P}function F(d,p,f){return d.type==="anthropic"?d.baseUrl.replace(/\/v1$/,"")+p+f:d.baseUrl+p.replace(/^\/v1/,"")+f}function ee(d,p){let f={};for(let[b,x]of Object.entries(d.headers))x===void 0||nl.has(b)||b.startsWith("x-token-lens-")||il.includes(b)&&(p.apiKey||a.clientKeys.length)||(f[b]=Array.isArray(x)?x.join(", "):x);if(f["accept-encoding"]="identity",!p.apiKey&&!a.clientKeys.length&&(p.type==="anthropic"&&!f["x-api-key"]&&/^Bearer /i.test(f.authorization??"")?(f["x-api-key"]=f.authorization.replace(/^Bearer /i,""),delete f.authorization):p.type==="openai"&&!f.authorization&&f["x-api-key"]&&!p.authHeader&&(f.authorization=`Bearer ${f["x-api-key"]}`,delete f["x-api-key"],delete f["anthropic-version"])),p.type==="anthropic"&&!f["anthropic-version"]&&(f["anthropic-version"]="2023-06-01"),p.apiKey){let b=p.authHeader??(p.type==="anthropic"?"x-api-key":"authorization");f[b]=b==="authorization"?`Bearer ${p.apiKey}`:p.apiKey,p.type==="anthropic"&&!f["anthropic-version"]&&(f["anthropic-version"]="2023-06-01")}return{...f,...p.headers}}function an(d){if(!a.clientKeys.length)return(Q(d,"x-token-lens-app")||"default").slice(0,64);let p=qr(d),f=p?a.clientKeys.find(b=>Ur(b.key,p)):void 0;return f?f.name:null}let Te=d=>{let p=qr(d);return!!a.adminKey&&!!p&&Ur(a.adminKey,p)},Ne=(d,p)=>!a.isolateTeams||Te(d)?void 0:p??"\0",me=(d,p)=>p===void 0?d:new Map([...d].filter(([f])=>f.split("\0")[0]===p)),We=async()=>y?y.customerTotals():s.snapshot(),pe=(d,p,f)=>Te(d)?p.searchParams.get("team")??void 0:f??"\0";async function Ke(){return y?y.totals():{}}async function be(d){let p=r.list().slice(0,d).map(b=>({...Bn(b),findings:Ln(b)}));if(!y)return p;let f=(await y.recentRuns(d)).filter(b=>!r.get(b.id));return[...p,...f].sort((b,x)=>String(x.lastSeen).localeCompare(String(b.lastSeen))).slice(0,d)}async function Ce(d,p,f,b){let x=b,P=f.pathname.replace(/\/+$/,""),A=/^\/token-lens\/batches\/(tlb_[0-9a-f]+)$/.exec(P);if(d.method==="GET"&&A){let k=b?u.take(A[1],b):void 0;if(!k)throw new $(404,"No such batch job for this key (results are handed over once, and kept for a day).");return le(p,200,{id:k.id,object:"token_lens.batch_job",status:k.status,response:k.response,error:k.error})}if(d.method==="GET"&&P==="/metrics"){p.writeHead(200,{"content-type":"text/plain; version=0.0.4"}),p.end(t.prometheus(Ne(d,b)));return}if(d.method==="GET"&&P==="/token-lens/report.csv"){let k=f.searchParams.get("by")==="run"?"run":"agent",w=Ne(d,b),M=k==="run"?(await be(2e3)).filter(D=>w===void 0||D.app===w):t.detail(me((await Ke()).rows??t.snapshot(),w));p.writeHead(200,{"content-type":"text/csv; charset=utf-8","content-disposition":`attachment; filename="token-lens-savings-by-${k}.csv"`,"cache-control":"no-store"}),p.end(Cr(M,k));return}if(d.method==="GET"&&(P==="/token-lens/report"||P==="/token-lens/report.json")){let k=Ne(d,b),w=(await be(k===void 0?50:2e3)).filter(V=>k===void 0||V.app===k).slice(0,50),M=await Ke(),D=t.json(me(M.rows??t.snapshot(),k),M.since),G=h.list().filter(V=>k===void 0||V.app===k),ae=s.list(Te(d)?void 0:b??"\0",await We());if(P.endsWith(".json"))return le(p,200,{...D,runs:w,switchedOff:G,byCustomer:ae.slice(0,100)});p.writeHead(200,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),p.end(Tr(D,w,G,ae));return}if(d.method==="GET"&&P==="/token-lens/stats"){let k=await Ke(),w=Ne(d,b);return le(p,200,{...t.json(me(k.rows??t.snapshot(),w),k.since),calibration:o.snapshot(),switchedOff:h.list().filter(M=>w===void 0||M.app===w),storage:y?.kind??"memory"})}if(d.method==="GET"&&P==="/token-lens/guard")return le(p,200,{switchedOff:h.list().filter(k=>Te(d)||k.app===b)});if(d.method==="POST"&&P==="/token-lens/guard/reset"){if(!Te(d))throw new $(401,"This endpoint needs the admin key.");let k=JSON.parse((await qn(d,a.maxBodyBytes)).toString("utf8")||"{}"),[w,M]=[typeof k.app=="string"?k.app:void 0,typeof k.agent=="string"?k.agent:void 0],D=h.reset(w,M);return le(p,200,{turnedBackOn:y?await y.resetGuard(w,M):D})}if(d.method==="GET"&&P==="/token-lens/runs"){let k=Math.min(500,Number(f.searchParams.get("limit"))||50),w=Ne(d,x)??f.searchParams.get("app"),M=(await be(w?2e3:k)).filter(D=>!w||D.app===w).slice(0,k).map(({findings:D,...G})=>({...G,topFinding:D?.[0]?.title}));return le(p,200,{runs:M})}let O=/^\/token-lens\/runs\/(.+)$/.exec(P);if(d.method==="GET"&&O){let k=decodeURIComponent(O[1]),w=Ne(d,x),M=r.get(k);if(M&&w!==void 0&&M.app!==w)throw new $(404,"No such run for this key.");if(M)return le(p,200,{...Bn(M),findings:Ln(M),outputChecks:M.checks,calls:M.calls});let D=await y?.run(k);if(D&&w!==void 0&&D.app!==w)throw new $(404,"No such run for this key.");if(!D)throw new $(404,"No such run (runs are kept in memory, most recent first, or in shared storage when configured).");return le(p,200,D)}if(d.method==="GET"&&(P==="/token-lens/customers"||P==="/token-lens/customers.json"||P==="/token-lens/customers.csv")){let k=s.list(pe(d,f,b),await We());if(P.endsWith(".csv")){p.writeHead(200,{"content-type":"text/csv; charset=utf-8","content-disposition":'attachment; filename="token-lens-savings-by-customer.csv"',"cache-control":"no-store"}),p.end(gt(k));return}let w=Math.min(1e4,Number(f.searchParams.get("limit"))||500);return le(p,200,{customers:k.slice(0,w),total:k.length})}let ke=/^\/token-lens\/customers\/(.+)$/.exec(P);if(d.method==="GET"&&ke){let k=pe(d,f,b)??"default",w=pt(decodeURIComponent(ke[1]),a.customers),M=(await We()).get(`${k}\0${w}`);if(!M)throw new $(404,"No calls for this customer yet (for the admin key, name the team with ?team=).");let D=f.searchParams.get("plan")??void 0,G;try{G={customer:ii(a.customers,D,()=>{}),team:ti(a.customers,k)}}catch(z){throw z instanceof _a?new $(400,z.message):z}let ae=s.view(k,w,M),V=s.remaining(k,w,G);return le(p,200,{...ae,limits:{customer:G.customer,team:G.team,left:V},summary:`Token Lens saved ${ae.savedTokens.toLocaleString("en-US")} tokens (${ae.savedTokensPct}%)`+(ae.costBeforeUsd?` and ${Zt(ae.savedUsd)} (${ae.savedUsdPct}%) on ${ae.requests.toLocaleString("en-US")} calls.`:` on ${ae.requests.toLocaleString("en-US")} calls.`)})}if(d.method==="GET"&&P==="/token-lens/models"){let k=Object.values(se).map(w=>({...w,calibration:o.snapshot()[w.id]}));return le(p,200,{models:k})}if(d.method==="POST"&&P==="/token-lens/analyze"){let k=JSON.parse((await qn(d,a.maxBodyBytes)).toString("utf8")||"{}");if(typeof k.prompt!="string"||typeof k.model!="string")throw new $(400,'Send {"prompt": "...", "model": "..."}.');return le(p,200,ar({prompt:k.prompt,model:k.model,conversationTokens:k.conversationTokens,level:k.level}))}let _=/^\/token-lens\/models(?:\/(.+))?$/.exec(P);if(_&&(d.method==="POST"||d.method==="DELETE")){if(!a.adminKey)throw new $(403,'Set TOKEN_LENS_ADMIN_KEY to manage models at runtime, or list them under "models" in the config file.');if(!Te(d))throw new $(401,"This endpoint needs the admin key.");if(d.method==="DELETE"&&_[1])return yi(decodeURIComponent(_[1])),le(p,200,{deleted:decodeURIComponent(_[1])});let k=JSON.parse((await qn(d,a.maxBodyBytes)).toString("utf8")||"{}");try{return le(p,201,{model:ki(k)})}catch(w){throw new $(400,w.message)}}throw new $(404,"Not found.")}function $e(d,p,f,b){if(d.headersSent){d.end();return}le(d,f,Pn(p,f,b))}let nn=d=>d==="anthropic-to-openai"?"/v1/chat/completions":"/v1/messages";function S(d,p){let f=JSON.parse(p.toString("utf8"));return Buffer.from(JSON.stringify(d==="anthropic-to-openai"?gr(f):hr(f)))}function j(d,p,f){let b=Un(f);return p>=300?Buffer.from(JSON.stringify(vr(d,b,p))):b?Buffer.from(JSON.stringify(d==="anthropic-to-openai"?kr(b):yr(b))):f}async function X(d,p,f,b,x,P,A,O){let ke=new AbortController;p.on("close",()=>{p.writableFinished||ke.abort()}),O&&x&&(x=S(O,x));let _=V=>i(F(b,O?nn(O):f.pathname,f.search),{method:d.method,headers:ee(d,b),body:V&&V.length&&d.method!=="GET"&&d.method!=="HEAD"?new Uint8Array(V):void 0,signal:ke.signal}),k=await _(x);A&&x&&(k=await ka(k,x,A,V=>_(V)));let w={};k.headers.forEach((V,z)=>{Gr.has(z)||(w[z]=V)}),Object.assign(w,P);let M=(w["content-type"]??"").includes("event-stream");if(O&&!M){let V=j(O,k.status,Buffer.from(await k.arrayBuffer()));w["content-type"]="application/json",p.writeHead(k.status,w),p.write(V);let z=ha(Un(V)??{});return{status:k.status,usage:z,replay:{at:Date.now(),status:k.status,headers:w,body:V,usage:z}}}p.writeHead(k.status,w);let D=new Ni(M);if(O&&k.body){let V=new On(O),z=new TextDecoder,Re=async Pe=>{if(!Pe)return;let ye=Buffer.from(Pe);D.push(ye),p.write(ye)||await new Promise(Je=>p.once("drain",Je))};for await(let Pe of k.body)await Re(V.push(z.decode(Pe,{stream:!0})));await Re(V.end())}else if(k.body)for await(let V of k.body)D.push(V),p.write(V)||await new Promise(z=>p.once("drain",z));let G=D.end(),ae=D.body?{at:Date.now(),status:k.status,headers:w,body:D.body,usage:G}:void 0;return{status:k.status,usage:G,replay:ae,streamText:D.streamText}}async function ka(d,p,f,b){if(d.ok||![400,408,422,429].includes(d.status))return d;let x=await d.text();if((d.status===400||d.status===422)&&!/service_tier|flex/i.test(x))return new Response(x,{status:d.status,headers:d.headers});let P=JSON.parse(p.toString("utf8"));return delete P.service_tier,f.fellBack=!0,b(Buffer.from(JSON.stringify(P)))}async function ia(d,p,f,b,x,P){P&&(b=S(P,b));let A=w=>i(F(f,P?nn(P):p.pathname,p.search),{method:"POST",headers:ee(d,f),body:new Uint8Array(w)}),O=await A(b);x&&(O=await ka(O,b,x,A));let ke={};O.headers.forEach((w,M)=>{Gr.has(M)||(ke[M]=w)});let _=Buffer.from(await O.arrayBuffer());P&&(_=j(P,O.status,_),ke["content-type"]="application/json");let k=Un(_);return{status:O.status,headers:ke,buf:_,json:k,usage:k?ha(k):{}}}async function Wr(d,p,f,b,x,P,A,O,ke){let _=zr(O);if(!_||typeof O.model!="string")return!1;let k=Date.now(),w=Ia.scope(x?`${b}\0${x}`:b,P,O),M=_.map(J=>Ia.key(w,J)),D=M.map(J=>I.get(J)),G=_.map((J,re)=>re).filter(J=>D[J]===void 0),ae,V={"content-type":"application/json"};if(G.length){let J=G.length===_.length?ke:Buffer.from(JSON.stringify({...O,input:G.map(ve=>_[ve])})),re=await ia(d,f,A,J);if(re.status>=300||!Array.isArray(re.json?.data)||re.json.data.length!==G.length)return p.writeHead(re.status,re.headers),p.end(re.buf),!0;for(let ve of re.json.data){let we=G[ve.index];we!==void 0&&(D[we]=ve.embedding,I.set(M[we],ve.embedding))}ae=re.json,V=re.headers}I.hits+=_.length-G.length,I.misses+=G.length;let z=Ca(O.model,"generic"),Re=z.id==="generic"?{...z,pricing:void 0}:z,Pe=J=>typeof J=="string"?o.count(J,Re):Array.isArray(J)?J.length:0,ye=_.reduce((J,re,ve)=>J+(G.includes(ve)?0:Pe(re)),0),Je=ae?.usage??{prompt_tokens:0,total_tokens:0},N={object:"list",data:D.map((J,re)=>({object:"embedding",index:re,embedding:J})),model:ae?.model??O.model,usage:Je};p.writeHead(200,{...V,"content-type":"application/json","x-token-lens-cached-embeddings":String(_.length-G.length),"x-token-lens-saved-tokens":String(ye)}),p.end(JSON.stringify(N));let Le=(Q(d,"x-token-lens-agent")||"-").slice(0,100);return t.record({app:b,agent:Le,run:"embeddings",profile:Re,status:200,usage:{inputTokens:Je.prompt_tokens??0},estimatedInput:0,savedInput:ye,replayed:!1}),s.record(b,x,{profile:Re,status:200,usage:{inputTokens:Je.prompt_tokens??0},estimatedInput:0,savedInput:ye,replayed:!1}),a.logRequests&&n(JSON.stringify({ts:new Date().toISOString(),app:b,model:O.model,upstream:P,embeddings:_.length,cached:_.length-G.length,saved:ye,ms:Date.now()-k})),!0}async function Kr(d,p,f,b){let x=Date.now(),P=f.pathname,A=d.method==="POST"?Ti(P):null,O=d.method==="GET"||d.method==="HEAD"?Buffer.alloc(0):await qn(d,a.maxBodyBytes),ke=(Q(d,"content-type")??"application/json").includes("json"),_;if(O.length&&ke)try{_=JSON.parse(O.toString("utf8"))}catch{if(A)throw new $(400,"The request body is not valid JSON.")}let[k,w]=L(A,P,typeof _?.model=="string"?_.model:void 0),M=mt(Q(d,"x-token-lens-customer"),_,a.customers),D=A==="anthropic"&&w.type==="openai"?"anthropic-to-openai":A==="openai-chat"&&w.type==="anthropic"?"openai-to-anthropic":void 0;if(d.method==="POST"&&P==="/v1/embeddings"&&_&&w.type==="openai"&&a.safe.cacheEmbeddings&&a.mode!=="off"&&Q(d,"x-token-lens-mode")!=="off"&&await Wr(d,p,f,b,M,k,w,_,O))return;if(!A||!_||typeof _!="object"){await X(d,p,f,w,O,{}),p.end();return}let G=["optimize","observe","off"].includes(Q(d,"x-token-lens-mode")??"")?Q(d,"x-token-lens-mode"):a.mode;if(G==="off"){await X(d,p,f,w,O,{},void 0,D),p.end();return}let ae=["light","balanced","aggressive","auto"].includes(Q(d,"x-token-lens-level")??"")?Q(d,"x-token-lens-level"):a.level,V=new Set((Q(d,"x-token-lens-allow")??"").split(",").map(m=>m.trim()).filter(Boolean)),z=Ai(A,_),Re=Ca(z.model,w.type==="anthropic"?"claude":"generic"),Pe=Re.pricing?Br(a.priceTiers,z.model):void 0,ye=Re.pricing?.longContext,Je=Pe?{aboveInputTokens:Pe.aboveInputTokens,inputPerMTok:Pe.inputPerMTok,outputPerMTok:Pe.outputPerMTok}:ye?{aboveInputTokens:ye.aboveTokens,inputPerMTok:ye.inputPerMTok,outputPerMTok:ye.outputPerMTok}:void 0,N=Je?{...Re,priceTier:Je}:Re,Le=Rn(z.refs),J=Q(d,"x-token-lens-run")?.slice(0,200),re=z.refs.find(m=>m.user)?.get()??"",ve=M?`${b}\0${M}`:b,we=J?M?`${b}:${M}:${J}`:`${b}:${J}`:Qa(ve,N.id,Le.system.join(`
3363
+ `),re),ta=(Q(d,"x-token-lens-agent")||"-").slice(0,100),q=r.open(we,b,!!J,ta);M&&(q.customer=M);let Hn=Qa(k,P,O.toString("utf8")),$r=q.requestHashes.has(Hn);q.requestHashes.size<5e3&&q.requestHashes.add(Hn);let Vn=Qa(Le.system.join(`
3364
+ `),Le.tools.join(`
3365
+ `)),Wn=q.prefixes.get(Vn)??0;q.prefixes.set(Vn,Wn+1);let Jr=(Array.isArray(_.tools)?_.tools:[]).map(m=>m?.function?.name??m?.name??"").filter(Boolean),Fi=jr(Le.system.join(`
3366
+ `),Le.tools,Jr),tn=Or(q.prefixPrint,Fi,Le.system.join(`
3367
+ `),Le.tools.join(`
3368
+ `));q.prefixPrint=Fi;let Gi=Dr(A,_),Yr=Nr(A,_),rn=Lr(z.toolCalls);if(rn.length){let m=E.get(ve);m||E.set(ve,m=new Map);for(let R of rn){let T=m.get(R);T||(m.size>=2e4&&m.delete(m.keys().next().value),m.set(R,T=new Set)),T.size<50&&T.add(we)}let v=new Set,C=0;for(let R of rn){let T=m.get(R);if(T.size>1){C++;for(let B of T)B!==we&&v.add(B)}}q.sharedReads=C?{files:C,of:rn.length,runs:v.size,agents:[...new Set([...v].map(R=>r.get(R)?.agent??"-"))].slice(0,5)}:void 0}let qi=m=>a.reportToolArgs?m:`input #${Qa(m).slice(0,8)}`,Kn=new Map;for(let m of z.toolCalls){let v=`${m.name}\0${m.args}`,C=Kn.get(v)??{name:m.name,args:qi(m.args),count:0};C.count++,Kn.set(v,C)}let Xr=[...Kn.values()].filter(m=>m.count>1),Ui,Ma=z.toolCalls.at(-1);if(Ma){let m=0;for(let v=z.toolCalls.length-1;v>=0&&z.toolCalls[v].name===Ma.name&&z.toolCalls[v].args===Ma.args;v--)m++;m>1&&(Ui={name:Ma.name,args:qi(Ma.args),times:m})}let Se=In(z.refs,N,o),$n=Se.parts.system+Se.parts.tools,ra={"x-token-lens-run":we,"x-token-lens-profile":N.id},Qr=()=>{let m=w.type==="anthropic"?"anthropic":"openai",v=An(A,_);if(!v.length)return;let C=Math.max(...v.map(T=>T.turn)),R=T=>vi(m,T)??0;return{count:v.length,tokens:v.reduce((T,B)=>T+R(B),0),oldTokens:v.filter(T=>T.turn<C-1).reduce((T,B)=>T+R(B),0),provider:m}},ya=(m,v,C,R,T={},B=1)=>{let ue={images:Qr(),at:new Date().toISOString(),model:z.model,profile:N.id,upstream:k,status:m,parts:C.parts,input:C.total,toolOutputs:C.toolOutputs,usage:v,actions:R,duplicate:$r,window:N.contextWindow,ms:Date.now()-x,costUsd:T.replayed||m>=400?0:ca(N,{...v,inputTokens:v.inputTokens??C.total})*B,costBeforeUsd:pn(N,{...v,inputTokens:v.inputTokens??C.total},R.reduce((xe,la)=>xe+la.saved,0)),toolCalls:z.toolCalls.length,repeatedToolCalls:Xr,sameCallStreak:Ui,api:A,...tn&&$n>=1024?{cacheBreak:{kind:tn.kind,where:tn.where,tokens:Math.round(tn.lostShare*$n)}}:{},...Gi?{jsonRetries:Gi,structuredOutput:Yr}:{},...N.priceTier?{priceTier:N.priceTier}:{},...B!==1?{priceFactor:B}:{},...T};r.record(q,ue),y?.markRun(q);let oa=R.reduce((xe,la)=>xe+la.saved,0);t.record({app:b,agent:q.agent,run:we,profile:N,status:m,usage:v,estimatedInput:C.total,savedInput:oa,replayed:!!T.replayed,priceFactor:B}),s.record(b,M,{profile:N,status:m,usage:v,estimatedInput:C.total,savedInput:oa,replayed:!!T.replayed,priceFactor:B}),a.logRequests&&n(JSON.stringify({ts:ue.at,app:b,run:we,model:z.model,profile:N.id,upstream:k,status:m,input:v.inputTokens??C.total,output:v.outputTokens,cached:v.cachedInputTokens,saved:oa,actions:R.map(xe=>xe.id),replayed:T.replayed||void 0,ms:ue.ms}))},Hi=`${ve}\0${Hn}`,Vi=a.safe.dedupeRetries&&G==="optimize"&&!z.stream&&z.temperature===0,sa=Vi?l.get(Hi):void 0;if(sa&&Date.now()-sa.at<=a.retryWindowSeconds*1e3){p.writeHead(sa.status,{...sa.headers,...ra,"x-token-lens-replayed":"true"}),ya(sa.status,sa.usage,Se,[],{replayed:!0}),p.end(sa.body);return}let sn=Number(Q(d,"x-token-lens-max-calls"))||a.runBudget.maxCalls,on=Number(Q(d,"x-token-lens-max-cost-usd"))||a.runBudget.maxCostUsd,Jn=q.calls.filter(m=>!m.replayed&&!m.overBudget&&m.status<400),Wi=Jn.reduce((m,v)=>m+v.costUsd,0);if(sn&&Jn.length>=sn||on&&Wi>=on){let m=`Token Lens stopped this run: it reached its budget (${Jn.length} calls, $${Wi.toFixed(4)} spent; limit ${[sn?`${sn} calls`:"",on?`$${on}`:""].filter(Boolean).join(" / ")}). Start a new run or raise the limit.`;p.writeHead(429,{"content-type":"application/json",...ra,"x-token-lens-budget":"exceeded"}),p.end(JSON.stringify(Pn(A,429,m))),ya(429,{},Se,[],{overBudget:!0});return}let va;try{va={customer:ii(a.customers,Q(d,"x-token-lens-plan")?.slice(0,64),m=>Q(d,m)),team:ti(a.customers,b)}}catch(m){throw m instanceof _a?new $(400,m.message):m}if(M||(va.customer={}),ri(va.customer)||ri(va.team)){let m=s.over(b,M,va);if(m){let C=m.limit.endsWith("Usd"),R=ue=>C?`$${ue.toFixed(4)}`:`${Math.round(ue).toLocaleString("en-US")} tokens`,T=m.limit.startsWith("daily")?"daily":"monthly",B=`Token Lens stopped this call: ${m.who==="customer"?`customer "${M}"`:"this team"} reached its ${T} limit (${R(m.spent)} of ${R(m.cap)}). It resets at the start of the next UTC ${T==="daily"?"day":"month"}.`;p.writeHead(429,{"content-type":"application/json",...ra,"x-token-lens-budget":`${m.who}-${T}-${C?"usd":"tokens"}`}),p.end(JSON.stringify(Pn(A,429,B))),ya(429,{},Se,[],{overBudget:!0});return}let v=s.remaining(b,M,va);v.usd!==void 0&&(ra["x-token-lens-budget-left-usd"]=v.usd.toFixed(6)),v.tokens!==void 0&&(ra["x-token-lens-budget-left-tokens"]=String(Math.floor(v.tokens)))}let Ki=Q(d,"x-token-lens-batch"),ln=Ki==="true"||Ki==="1",ze=h.configFor(a,b,ta,V,!!z.stream||ln),$i=ze.cfg.optIn.warmCache||(ze.allow.has("warm-cache")?{maxWaitMs:15e3}:!1),cn,un;if($i&&G==="optimize"&&!ln&&$n>=1024&&ze.cfg.safe.promptCaching){let m=[b,k,z.model,Vn].join("\0"),v=H.get(m);if(v){let C=Date.now(),R;await Promise.race([v,new Promise(T=>R=setTimeout(T,$i.maxWaitMs))]),clearTimeout(R),cn=Date.now()-C}else if(!W.has(m)){let C;H.set(m,new Promise(R=>C=R)),un=()=>{H.has(m)&&(H.delete(m),W.add(m),W.size>5e3&&W.delete(W.values().next().value),C())},p.on("close",un)}}let Z={actions:[],tips:[]},ie=Se;if(G==="optimize"){let m={cfg:ze.cfg,body:_,parsed:z,profile:N,upstream:w,counter:o,prefixRepeats:un?Math.max(Wn,1):Wn,runId:we,level:ae,allow:ze.allow,conversationTokens:Se.total-Se.parts.prompt-Se.parts.context};Z=rr(m),Z.actions.length&&(ie=In(z.refs,N,o));let v=sr(m,ie);v&&Z.actions.push(v),cn!==void 0&&Z.actions.push({id:"warm-cache",saved:0})}let Zr=ze.cfg.optIn.flex||ze.allow.has("flex"),es=w.flex??(w.type==="openai"&&/(^|\.)api\.openai\.com$/.test(new URL(w.baseUrl).hostname)),Ye=Zr&&es&&A!=="anthropic"&&!ln&&_.service_tier===void 0?{fellBack:!1}:void 0;if(Ye&&(_.service_tier="flex",Z.actions.push({id:"flex",saved:0})),a.blockOverContext&&ie.total+(z.maxOutputTokens??0)>N.contextWindow){let m=`This request needs about ${ie.total+(z.maxOutputTokens??0)} tokens but ${N.label} has a ${N.contextWindow}-token context window. Rejected by Token Lens before it was sent.`;$e(p,A,400,m),ya(400,{},ie,Z.actions);return}if(ln){if(z.stream)return $e(p,A,400,"Requests sent with x-token-lens-batch can't stream.");let m=u.canBatch(A,P,w);if(m)return $e(p,A,400,m);let v=ee(d,w);for(let T of["content-length","host","accept-encoding"])delete v[T];let C=[...Z.actions,{id:"batch",saved:0}],R=u.add({app:b,protocol:A,path:P,upstream:k,body:_,onDone:(T,B)=>ya(B?200:502,T,ie,C,{},B?a.batch.discount:1)},w,v);p.writeHead(202,{"content-type":"application/json",...ra,"x-token-lens-batch-id":R.id}),p.end(JSON.stringify({id:R.id,object:"token_lens.batch_job",status:R.status,result_url:`/token-lens/batches/${R.id}`}));return}let Ji=ji({...q,calls:[...q.calls,{parts:ie.parts,status:200}]}),as=Z.actions.reduce((m,v)=>m+v.saved,0),ge={...ra,"x-token-lens-input-tokens":String(ie.total),"x-token-lens-saved-tokens":String(as)};Z.actions.length&&(ge["x-token-lens-actions"]=Z.actions.map(m=>m.id).join(","));let Yi=Z.tips.filter(m=>m.id!=="lighter-model");Yi.length&&(ge["x-token-lens-tips"]=Yi.map(m=>m.id).join(",")),Ji&&(ge["x-token-lens-growing"]=Ji),cn!==void 0&&(ge["x-token-lens-warm-wait-ms"]=String(cn)),N.priceTier&&ie.total>.9*N.priceTier.aboveInputTokens&&(ge["x-token-lens-price-tier"]=`${ie.total>N.priceTier.aboveInputTokens?"above":"near"} ${N.priceTier.aboveInputTokens}`);let Xi=ze.cfg.optIn.lazyTools||(ze.allow.has("lazy-tools")?{minTools:8}:!1),Ie=G==="optimize"&&Xi?ur(A,_,Xi.minTools):null,Yn=ze.cfg.optIn.parkToolOutputs||(ze.allow.has("park-tool-outputs")?{minTokens:1500,keepLast:1}:!1),ns=Ie||Yn?structuredClone(_):void 0,Xe=G==="optimize"&&Yn&&!z.stream&&(A==="openai-chat"||A==="anthropic")&&_.tool_choice!=="none"?Sr(z,Yn,o,N,q.parked??=new Map):[];if(q.parked&&q.parked.size>50)for(let m of[...q.parked.keys()].slice(0,q.parked.size-50))q.parked.delete(m);let Qi=h.onProbation(b,ta,[...Z.actions.map(m=>m.id),...Ie?["lazy-tools"]:[],...Xe.length?["park-tool-outputs"]:[]]),Xn=Qi.length?ia(d,f,w,O,void 0,D).catch(()=>{}):void 0,ne;if(Ie||Xe.length){let m=q.loadedTools??=new Set;for(let he of z.toolCalls)m.add(he.name);let v={},C=0,R=0,T,B=!1;for(;R<4&&!T;R++){let he=Ie?dr(A,_,Ie,m):[];Xe.length&&!(_.tools??=[]).some(Qe=>(Qe?.function?.name??Qe?.name)===He)&&_.tools.push(wr(A));let _e=await ia(d,f,w,Buffer.from(JSON.stringify(_)),Ye,D);if(v=Ii(v,_e.usage),_e.status>=300){T=_e;break}let ei=Er(A,_e.json),st=Xe.length?ei.filter(Qe=>Qe.name===He):[],ai=he.length?mr(A,_e.json,he):[];if(!st.length&&!ai.length){T=_e;break}C+=_e.usage.inputTokens??0;for(let Qe of ai)m.add(Qe);if(st.length){if(ei.some(wa=>wa.name!==He&&wa.name!==fa))break;let Qe=new Map(ei.map(wa=>[wa.id,wa.name===He?_r(q.parked,wa.args):`Loaded: ${ai.join(", ")||"none"}. Their full definitions are now in the tool list.`]));Ar(A,_,_e.json,Qe)}}T||(B=!0,Object.keys(_).forEach(he=>delete _[he]),Object.assign(_,ns,Ie?{tools:Ie.original}:{}),T=await ia(d,f,w,Buffer.from(JSON.stringify(_)),Ye,D),v=Ii(v,T.usage));let ue=In(Ai(A,_).refs,N,o),oa=ie.total-ue.total-C,xe=Ie&&!B?Math.max(0,ie.parts.tools-ue.parts.tools):0,la=Xe.length&&!B?Math.max(0,oa+C-xe):0,rt=(he,_e)=>xe+la?Math.round(oa*he/(xe+la)):_e?Math.round(oa/((Ie?1:0)+(Xe.length?1:0))):0;Ie&&(xe||R>1||B)&&Z.actions.push({id:"lazy-tools",saved:rt(xe,!0),count:R-1}),Xe.length&&Z.actions.push({id:"park-tool-outputs",saved:rt(la,!0),count:Xe.length});for(let he of De(A,T.json).toolCalls)m.add(he.name);ie={...ue,total:ue.total},ge["x-token-lens-input-tokens"]=String(ie.total),ge["x-token-lens-saved-tokens"]=String(Z.actions.reduce((he,_e)=>he+_e.saved,0)),ge["x-token-lens-actions"]=Z.actions.map(he=>he.id).join(","),ne={...T,usage:v}}else Xn&&(ne=await ia(d,f,w,Buffer.from(JSON.stringify(_)),Ye,D));let dn,Qn=!1;if(ne&&Xn){let m=await Xn,v=Qi.filter(C=>Z.actions.some(R=>R.id===C));if(m&&m.status<300&&v.length){let C=De(A,m.json),R=jn(De(A,ne.json),C,Z.actions.reduce((T,B)=>T+B.saved,0),a.verify.minSimilarity);ne.status<300&&R.match?(h.confirm(b,ta,v),dn={check:R,ids:v,originalOutput:C,costUsd:ca(N,m.usage),tokens:(m.usage.inputTokens??0)+(m.usage.outputTokens??0)}):(dn={check:{...R,match:!1},ids:v,originalOutput:C,costUsd:ca(N,ne.usage),tokens:(ne.usage.inputTokens??0)+(ne.usage.outputTokens??0)},ne=m,Qn=!0,ie=Se,ge["x-token-lens-input-tokens"]=String(Se.total),ge["x-token-lens-saved-tokens"]="0",ge["x-token-lens-answer"]="original",delete ge["x-token-lens-actions"])}}let ce;if(ne)p.writeHead(ne.status,{...ne.headers,...ge}),p.write(ne.buf),ce={status:ne.status,usage:ne.usage,replay:{at:Date.now(),status:ne.status,headers:ne.headers,body:ne.buf,usage:ne.usage}};else{let m=Z.actions.length?Buffer.from(JSON.stringify(_)):O;ce=await X(d,p,f,w,m,ge,Ye,D)}ce.usage.inputTokens&&!Ie&&!Qn&&o.observe(N,ie.raw,ce.usage.inputTokens),Vi&&ce.replay&&ce.status<300&&(l.set(Hi,ce.replay),l.size>500&&l.delete(l.keys().next().value));let mn=Qn?[]:Z.actions.filter(m=>m.id!=="flex"||!Ye?.fellBack);ya(ce.status,ce.usage,ie,mn,{},Ye&&!Ye.fellBack&&ce.status<300?a.flexDiscount:1),un?.(),p.end();let Zi=`${b}\0${q.agent}`,Oe=g.get(Zi)??{checks:0,checkTokens:0,saved:0};g.set(Zi,Oe);let Zn=mn.reduce((m,v)=>m+v.saved,0);Oe.saved+=Zn;let et=()=>{if(!z.stream)return O;let{stream:m,stream_options:v,...C}=JSON.parse(O.toString("utf8"));return Buffer.from(JSON.stringify(C))},at=(m,v,C)=>{let R={...m,actions:v,costUsd:C};return q.checks.push(R),y?.markRun(q),q.checks.length>200&&q.checks.shift(),t.recordCheck(b,q.agent,N,m.match,C),a.logRequests&&n(JSON.stringify({ts:m.at,app:b,run:we,outputCheck:m.match?"same":"different",similarity:m.similarity,sameToolCalls:m.sameToolCalls})),R},nt=async(m,v,C)=>{let R=await ia(d,f,w,et(),void 0,D);if(R.status<300&&(Oe.checkTokens+=(R.usage.inputTokens??Se.total)+(R.usage.outputTokens??0),t.recordCheck(b,q.agent,N,!0,ca(N,R.usage),!1),!jn(De(A,R.json),v,0,a.verify.minSimilarity).match)){m.modelVaries=!0;return}let T=h.suspend(b,ta,C,m);y&&T.length&&await y.suspend(h.list().filter(B=>B.app===b&&B.agent===ta&&T.includes(B.fix))),T.length&&n(JSON.stringify({ts:new Date().toISOString(),level:"warn",app:b,agent:ta,switchedOff:T,reason:"an output check found a different answer"}))},it=m=>{let v=m().catch(C=>n(JSON.stringify({ts:new Date().toISOString(),level:"error",outputCheck:String(C?.message??C)})));c.add(v),v.finally(()=>c.delete(v))};if(dn){let m=dn;Oe.checks++,Oe.checkTokens+=m.tokens;let v=at(m.check,m.ids,m.costUsd);m.check.match||it(()=>nt(v,m.originalOutput,m.ids));return}let is=mn.some(m=>za.has(m.id))&&a.verify.sampleRate>0?Math.max(a.verify.sampleRate,.25):a.verify.sampleRate,ts=Q(d,"x-token-lens-verify")==="1",rs=Oe.checks<a.verify.freeChecks||Oe.checkTokens<Oe.saved*a.verify.maxShareOfSavings,tt=z.stream?ce.streamText!==void 0?lr(A,ce.streamText):void 0:ce.replay?De(A,Un(ce.replay.body)):void 0;Zn>0&&ce.status<300&&tt&&(ts||rs&&Math.random()<is)&&(Oe.checks++,it(async()=>{let m=await ia(d,f,w,et(),void 0,D);if(m.status>=300)return;let v=m.usage;Oe.checkTokens+=(v.inputTokens??ie.total)+(v.outputTokens??0);let C=De(A,m.json),R=jn(tt,C,Zn,a.verify.minSimilarity),T=mn.filter(ue=>ue.saved>0).map(ue=>ue.id),B=at(R,T,ca(N,v));R.match||await nt(B,C,T)}))}let Bi=el(async(d,p)=>{let f=new URL(d.url??"/","http://gateway"),b=Ti(f.pathname);try{if(d.method==="GET"&&(f.pathname==="/healthz"||f.pathname==="/"))return le(p,200,{ok:!0,service:"token-lens-gateway",upstreams:Object.keys(a.upstreams),mode:a.mode});let x=an(d);if(f.pathname==="/metrics"||f.pathname.startsWith("/token-lens/")){let P=/^\/token-lens\/models/.test(f.pathname)&&d.method!=="GET";if(!x&&!Te(d)&&!P)throw new $(401,"Missing or unknown Token Lens key.");return await Ce(d,p,f,x)}if(!f.pathname.startsWith("/v1/"))throw new $(404,"Not found. Point your SDK's base URL at this gateway (OpenAI: <gateway>/v1, Anthropic: <gateway>).");if(!x)throw new $(401,"Missing or unknown Token Lens key.");await Kr(d,p,f,x)}catch(x){if(x instanceof $)return $e(p,b,x.status,x.message);if(x.name==="AbortError")return;n(JSON.stringify({ts:new Date().toISOString(),level:"error",path:f.pathname,error:String(x.message??x)})),$e(p,b,502,`Upstream request failed: ${x.message}`)}});return Bi.on("close",()=>{u.stop(),y?.stop()}),{server:Bi,cfg:a,runs:r,metrics:t,counter:o,batches:u,guard:h,storage:y,settle:()=>Promise.all([...c]).then(()=>{})}}var na=ft(),{server:Vr}=Hr(na),Li=Object.entries(na.upstreams);Li.length||console.warn("token-lens: no upstreams configured. Set OPENAI_API_KEY / ANTHROPIC_API_KEY or TOKEN_LENS_CONFIG.");!na.clientKeys.length&&Li.some(([,a])=>a.apiKey)&&console.warn("token-lens: no client keys set, so anyone who can reach this port can use the upstream keys. Set TOKEN_LENS_CLIENT_KEYS unless the network is private.");Vr.listen(na.port,na.host,()=>{console.log(`token-lens gateway on http://${na.host}:${na.port} (mode: ${na.mode}; upstreams: ${Li.map(([a,e])=>`${a}=${e.type}`).join(", ")||"none"})`)});for(let a of["SIGINT","SIGTERM"])process.on(a,()=>{Vr.close(()=>process.exit(0)),setTimeout(()=>process.exit(0),5e3).unref()});