@lmctl-ai/lmctl 0.2.2 → 0.2.3

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/dist/cli/index.js CHANGED
@@ -2321,7 +2321,7 @@ messages. No timestamps, tool activity, or truncation.
2321
2321
  context, one paragraph per prompt with a blank line between prompts.
2322
2322
  Codex prompts require native prompt metadata or user_message events;
2323
2323
  unclassified user-role records are omitted in this compact mode.
2324
- `});import{mkdirSync as n_,readFileSync as jx,renameSync as Bx,writeFileSync as Wx,existsSync as s_}from"node:fs";import{homedir as Hx}from"node:os";import{dirname as i_,join as Gi,resolve as Ji}from"node:path";import{fileURLToPath as Xx}from"node:url";function Kx(){return Gi(Hx(),".lmctl","cache","lmprice")}function en(t,e){return Gi(t,e)}function yr(t){try{return JSON.parse(jx(t,"utf-8"))}catch{return null}}function a_(t,e){let r=`${t}.tmp-${process.pid}`;Wx(r,e),Bx(r,t)}function yc(t){return t===null||typeof t=="number"}function Vi(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.schema_version!==1||!Array.isArray(e.records)||e.records.length===0?!1:e.records.every(r=>{if(typeof r!="object"||r===null)return!1;let n=r;if(typeof n.source!="string"||typeof n.source_model_id!="string"||typeof n.pricing!="object"||n.pricing===null)return!1;let s=n.pricing;return yc(s.input_per_1m_tokens)&&yc(s.output_per_1m_tokens)&&yc(s.input_cache_read_per_1m_tokens)})}function Ki(t){if(typeof t!="object"||t===null)return!1;let e=t;if(e.schema_version!==1||!Array.isArray(e.standards)||!Array.isArray(e.aliases))return!1;let r=e.standards.every(s=>{if(typeof s!="object"||s===null)return!1;let i=s;return typeof i.standard_slug=="string"&&(i.catalog_record_id===null||typeof i.catalog_record_id=="string")}),n=e.aliases.every(s=>{if(typeof s!="object"||s===null)return!1;let i=s;return typeof i.alias=="string"&&(i.standard_slug===null||typeof i.standard_slug=="string")&&typeof i.evidence=="string"&&zx.has(i.evidence)});return r&&n}function Qx(t){let e=yr(en(t,o_)),r={etag:typeof e?.model_list?.etag=="string"?e.model_list.etag:null,last_checked:typeof e?.model_list?.last_checked=="string"?e.model_list.last_checked:null},n={etag:typeof e?.aliases?.etag=="string"?e.aliases.etag:null,last_checked:typeof e?.aliases?.last_checked=="string"?e.aliases.last_checked:null};if(e===null){let s=yr(en(t,Yx));s&&(r.etag=typeof s.etag=="string"?s.etag:null,r.last_checked=typeof s.fetchedAt=="string"?s.fetchedAt:null)}return{model_list:r,aliases:n}}function Zx(t){let e=Qx(t),r=yr(en(t,Ec)),n=yr(en(t,Tc));return{catalog:Vi(r)?r:null,aliases:Ki(n)?n:null,meta:e}}function eR(t,e){try{n_(t,{recursive:!0}),a_(en(t,o_),JSON.stringify(e))}catch{}}function zg(t,e,r){try{n_(t,{recursive:!0}),a_(en(t,e),JSON.stringify(r))}catch{}}function tR(t,e){let r=rR(t),n=r?[Ji(r,"data",e)]:[Ji(t,"..","..","data",e)];for(let s of n)if(s_(s))return s;return null}function rR(t){let e=Ji(t);for(;;){if(s_(Ji(e,"package.json")))return e;let r=i_(e);if(r===e)return null;e=r}}function Qg(t,e,r){let n=r!==void 0?r:tR(t,e);return n===null?null:yr(n)}function nR(){let t=process.env.LMCTL_PRICE_TTL;if(t===void 0||t==="")return Yg;let e=Number(t);return!Number.isFinite(e)||e<0?Yg:e*1e3}function sR(){let t=process.env.LMCTL_PRICE_DATA;return t!==void 0&&t!==""?t:null}async function Zg(t,e,r,n){try{let s=await t(e,{method:"HEAD",signal:AbortSignal.timeout(Jx)});if(!s.ok)return{kind:"failed"};let i=s.headers.get("etag");if(r!==null&&i!==null&&i===n)return{kind:"match"};let o=await t(e,{signal:AbortSignal.timeout(Vx)});return o.ok?{kind:"payload",payload:await o.json(),etag:o.headers.get("etag")??i}:{kind:"failed"}}catch{return{kind:"failed"}}}function Yi(t={}){return Object.keys(t).length===0?(e_??=t_(t),e_):t_(t)}async function t_(t){let e=i_(Xx(import.meta.url)),r=t.pinDir!==void 0?t.pinDir:sR();if(r!==null&&r!==""){let g=yr(Gi(r,Ec)),h=yr(Gi(r,Tc));if(Vi(g)&&Ki(h)){let _={catalog:g,aliases:h,source:"pinned",generatedAt:g.generated_at??null};return wc=_.generatedAt,_}return r_(t,e)}let n=t.fetchImpl??fetch,s=t.cacheDir??Kx(),i=t.now??Date.now(),o=t.ttlMs??nR(),a=Zx(s),l=(g,h)=>g!==null&&h.last_checked!==null&&i-Date.parse(h.last_checked)<o,c=a.catalog,u=a.aliases,d=!1,f={model_list:{...a.meta.model_list},aliases:{...a.meta.aliases}},m=!1;if(!l(c,a.meta.model_list)){let g=await Zg(n,qx,c,a.meta.model_list.etag);g.kind==="match"?(f.model_list.last_checked=new Date(i).toISOString(),m=!0):g.kind==="payload"&&(f.model_list.last_checked=new Date(i).toISOString(),m=!0,Vi(g.payload)&&(c=g.payload,g.etag!==null&&(f.model_list.etag=g.etag),zg(s,Ec,c),d=!0))}if(!l(u,a.meta.aliases)){let g=await Zg(n,Gx,u,a.meta.aliases.etag);g.kind==="match"?(f.aliases.last_checked=new Date(i).toISOString(),m=!0):g.kind==="payload"&&(f.aliases.last_checked=new Date(i).toISOString(),m=!0,Ki(g.payload)&&(u=g.payload,g.etag!==null&&(f.aliases.etag=g.etag),zg(s,Tc,u),d=!0))}if((m||d)&&eR(s,f),c!==null||u!==null){let g={catalog:c,aliases:u,source:d?"network":"cache",generatedAt:c?.generated_at??null};return wc=g.generatedAt,g}return r_(t,e)}function r_(t,e){let r=Qg(e,"price-data.json",t.bundledPath),n=Qg(e,"price-aliases.json",t.bundledAliasesPath),s=Vi(r)?r:null,i=Ki(n)?n:null,o={catalog:s,aliases:i,source:s!==null||i!==null?"bundled":"unavailable",generatedAt:s?.generated_at??null};return wc=o.generatedAt,o}function l_(t,e){if(e===null)return null;let{input_per_1m_tokens:r,output_per_1m_tokens:n,input_cache_read_per_1m_tokens:s}=e;if(r===null||n===null)return null;let i=s??r,o=t.input/1e6*r+t.output/1e6*n+t.cachedInput/1e6*i;return Number(o.toPrecision(10))}var qx,Gx,Jx,Vx,Yg,Ec,Tc,o_,Yx,zx,wc,e_,vc=k(()=>{"use strict";qx="https://lmctl.com/dataset/model_list.json",Gx="https://lmctl.com/dataset/aliases.json",Jx=1e3,Vx=1e4,Yg=6*60*60*1e3;Ec="model_list.json",Tc="aliases.json",o_="meta.json",Yx="model_list.meta.json";zx=new Set(["established","asserted","unresolved"]);wc=null,e_=null});function ss(t){return t.toLowerCase().replace(/(\d)\.(\d)/g,"$1-$2")}function Er(t){let e=t.source_model_id.toLowerCase(),r=e.slice(e.lastIndexOf("/")+1);return ss(r)}function d_(t){let e=new Set,r=n=>{let s=n.toLowerCase().split("/");for(let i=0;i<s.length;i+=1)e.add(ss(s.slice(i).join("/")))};return r(t.source_model_id),t.gateway_id&&r(t.gateway_id),e}function iR(t,e){let r=new Set,n=l=>{r.add(ss(l))},s=t.trim().toLowerCase(),i=null,o=s.indexOf(":");o>0&&!s.slice(0,o).includes("/")&&(i=s.slice(0,o),n(s),s=s.slice(o+1)),n(s);let a=s.slice(s.lastIndexOf("/")+1);n(a);for(let l of e)n(`${l}/${a}`);return i!==null&&n(`${i}/${a}`),[...r]}function tn(t){let e=n=>!(n.mode!==void 0&&n.mode!==null&&n.mode!=="chat"||t.nonChatName&&t.nonChatName.test(n.source_model_id.toLowerCase())),r=n=>e(n)&&t.family.test(n.source_model_id.toLowerCase());return{firstPartyProviders:t.firstPartyProviders,isChatModel:e,coversRecord:r,normalize:n=>iR(n,t.vendorPrefixes),matchRow(n,s){if(!r(n))return!1;let i=d_(n);return s.some(o=>i.has(o))}}}function aR(t){let e=t.trim(),r=oR.exec(e);return r?{model:e.slice(0,r.index).trim(),effort:r[1].trim()}:{model:e,effort:null}}function zi(t){return t==="moonshot"?0:t==="litellm"?1:t==="openrouter"?2:t==="manual"?3:4}function uR(t){return{route:t.record_id??`${t.source}:${t.source_model_id}`,source:t.source,sourceModelId:t.source_model_id,provider:t.provider??null,pricing:t.pricing,estimated:t.source==="manual"}}function __(t,e){return t.map(uR).sort((r,n)=>{let s=zi(r.source)-zi(n.source);if(s!==0)return s;let i=r.provider!==null&&e.includes(r.provider)?0:1,o=n.provider!==null&&e.includes(n.provider)?0:1;return i!==o?i-o:r.sourceModelId.localeCompare(n.sourceModelId)})}function Sc(t){return t.pricing.input_per_1m_tokens!==null&&t.pricing.output_per_1m_tokens!==null}function mR(t,e,r){let n=__(t,r),i=t.find(o=>(o.record_id??`${o.source}:${o.source_model_id}`)===n[0].route)?.context_window?.input_tokens??void 0;return{id:n[0].sourceModelId,normalizedId:e,offers:n,...i!=null?{contextWindow:i}:{}}}function bc(t,e,r){if(t.length===0)return{kind:"known-unpriced",id:e};let n=mR(t,e,r),s=n.offers.find(Sc);return s===void 0?{kind:"known-unpriced",id:e}:s.estimated?{kind:"estimated",model:n}:{kind:"priced",model:n}}function fR(t,e){return t.standards.find(r=>r.standard_slug.toLowerCase()===e.toLowerCase())??null}function pR(t,e,r){let n=t.standard_slug;if(e===null||e.catalog_record_id===null)return{kind:"known-unpriced",id:n};let s=e.catalog_record_id.toLowerCase(),i=r.records.find(l=>(l.record_id??`${l.source}:${l.source_model_id}`).toLowerCase()===s);if(!i)return{kind:"known-unpriced",id:n};let o=Er(i),a=r.records.filter(l=>Er(l)!==o?!1:l.mode===void 0||l.mode===null||l.mode==="chat");return a.length===0?{kind:"known-unpriced",id:n}:bc(a,o,Ic)}function y_(t,e,r,n){if(r===null||!Array.isArray(r.records))return{state:{kind:"no-catalog"},viaAlias:!1,pinRoute:null};if(n!==null){let h=[e.trim().toLowerCase()];h.push(`${t.toLowerCase()}/${h[0]}`);let _=n.aliases.find(p=>h.includes(p.alias.toLowerCase()));if(_){if(_.evidence==="unresolved"||_.standard_slug===null)return{state:{kind:"unresolved",alias:_.alias},viaAlias:!0,pinRoute:null};let p=fR(n,_.standard_slug);return{state:pR(_,p,r),viaAlias:!0,pinRoute:p?.catalog_record_id?.toLowerCase()??null}}}let s=Qi[t];if(!s)return{state:{kind:"no-catalog"},viaAlias:!1,pinRoute:null};let i=e.trim().toLowerCase(),o=s.normalize(e),a=h=>({state:h,viaAlias:!1,pinRoute:null}),l=ss(i),c=r.records.filter(h=>h.source_model_id.toLowerCase()===i&&s.matchRow(h,[l]));if(c.length>0){let h=Er(c[0]),_=r.records.filter(p=>s.matchRow(p,[h])&&Er(p)===h);return a(bc(_.length>0?_:c,h,c_[t]??Ic))}let u=r.records.filter(h=>s.matchRow(h,o));if(u.length===0)return a({kind:"unknown",declared:e});let d=new Map;for(let h of u){let _=Er(h),p=d.get(_);p?p.push(h):d.set(_,[h])}let f=c_[t]??Ic,m=null,g=null;for(let h of d.values()){let _=__(h,f);(g===null||hR(_[0],g[0],f)<0)&&(m=h,g=_)}return a(bc(m,Er(m[0]),f))}function Zi(t,e,r,n){return y_(t,e,r,n).state}function E_(t,e,r,n){let{state:s,viaAlias:i,pinRoute:o}=y_(t,e,r,n);if(s.kind!=="priced"&&s.kind!=="estimated")return{state:s,offer:null,provenance:null};let a=s.model.offers;if(i&&o!==null){let c=a.find(u=>u.route.toLowerCase()===o);if(c!==void 0&&Sc(c))return{state:s,offer:c,provenance:"alias-pin"}}let l=a.find(Sc)??null;return{state:s,offer:l,provenance:i&&o!==null?"alias-pin":"route-preference"}}function T_(t,e){let r=Qi[e];if(!r)return null;let n=new Set;for(let s of t.records)r.coversRecord(s)&&n.add(Er(s));return n.size}function hR(t,e,r){let n=zi(t.source)-zi(e.source);if(n!==0)return n;let s=t.provider!==null&&r.includes(t.provider)?0:1,i=e.provider!==null&&r.includes(e.provider)?0:1;return s!==i?s-i:t.sourceModelId.localeCompare(e.sourceModelId)}var u_,m_,f_,p_,h_,g_,oR,lR,cR,dR,Qi,c_,Ic,Ac=k(()=>{"use strict";u_=tn({vendorPrefixes:["anthropic"],family:/claude/,firstPartyProviders:["anthropic"]}),m_=tn({vendorPrefixes:["openai"],family:/(^|\/)(gpt-|o\d|chatgpt|ft:gpt)|openai\//,firstPartyProviders:["openai"],nonChatName:/(^|[-/])(tts|transcribe(?:-\w+)?|realtime(?:-\w+)?|search(?:-\w+)*|image(?:-\w+)?|audio(?:-\w+)?|whisper(?:-\w+)?|dall-e(?:-\w+)?|embedding|moderation)(-|$)/}),f_=tn({vendorPrefixes:["google","gemini"],family:/gemini|gemma/,firstPartyProviders:["gemini","google","vertex_ai-language-models"],nonChatName:/embedding|imagen|-image|tts|audio|veo|lyria|live|realtime|video/}),p_=tn({vendorPrefixes:["moonshot","moonshotai"],family:/kimi|moonshot/,firstPartyProviders:["moonshot"]}),h_=tn({vendorPrefixes:["dashscope","qwen"],family:/qwen/,firstPartyProviders:["dashscope"]}),g_=tn({vendorPrefixes:["deepseek","nousresearch"],family:/deepseek|nous|hermes-\d/,firstPartyProviders:["deepseek","nousresearch"]}),oR=/\s*\(([^()]+)\)\s*$/;lR={"gemini 3.8 flash":"gemini-3.8-flash","gemini 3.7 flash":"gemini-3.7-flash","gemini 3.6 flash":"gemini-3.6-flash","gemini 3.1 pro":"gemini/gemini-3.1-pro-preview"},cR=["gemini","google","vertex_ai-language-models"],dR={normalize(t){let{model:e}=aR(t),r=lR[e.toLowerCase()];return r===void 0?[]:[ss(r)]},isChatModel(){return!0},coversRecord(t){return/gemini/.test(t.source_model_id.toLowerCase())},matchRow(t,e){if(!this.coversRecord(t))return!1;let r=d_(t);return e.some(n=>r.has(n))}},Qi={claude:u_,codex:m_,gemini:f_,agy:dR,kimi:p_,qwen:h_,hermes:g_},c_={claude:u_.firstPartyProviders,codex:m_.firstPartyProviders,gemini:f_.firstPartyProviders,agy:cR,kimi:p_.firstPartyProviders,qwen:h_.firstPartyProviders,hermes:g_.firstPartyProviders};Ic=[]});var w_={};me(w_,{runCost:()=>TR});function _R(t,e,r,n){let s=new Set,i=[];for(let o of e){let a=r===null?null:Zi(t,o,r,n),l=a?.kind==="priced"||a?.kind==="estimated"?`id:${a.model.normalizedId}`:a?.kind==="known-unpriced"?`id:${a.id}`:`raw:${o.trim().toLowerCase()}`;s.has(l)||(s.add(l),i.push(o))}return i}async function TR(t,e={stdout:process.stdout,stderr:process.stderr}){if(t.includes("--help")||t.includes("-h"))return e.stdout.write(`${ER}
2324
+ `});import{mkdirSync as n_,readFileSync as jx,renameSync as Bx,writeFileSync as Wx,existsSync as s_}from"node:fs";import{homedir as Hx}from"node:os";import{dirname as i_,join as Gi,resolve as Ji}from"node:path";import{fileURLToPath as Xx}from"node:url";function Kx(){return Gi(Hx(),".lmctl","cache","lmprice")}function en(t,e){return Gi(t,e)}function yr(t){try{return JSON.parse(jx(t,"utf-8"))}catch{return null}}function a_(t,e){let r=`${t}.tmp-${process.pid}`;Wx(r,e),Bx(r,t)}function yc(t){return t===null||typeof t=="number"}function Vi(t){if(typeof t!="object"||t===null)return!1;let e=t;return e.schema_version!==1||!Array.isArray(e.records)||e.records.length===0?!1:e.records.every(r=>{if(typeof r!="object"||r===null)return!1;let n=r;if(typeof n.source!="string"||typeof n.source_model_id!="string"||typeof n.pricing!="object"||n.pricing===null)return!1;let s=n.pricing;return yc(s.input_per_1m_tokens)&&yc(s.output_per_1m_tokens)&&yc(s.input_cache_read_per_1m_tokens)})}function Ki(t){if(typeof t!="object"||t===null)return!1;let e=t;if(e.schema_version!==1||!Array.isArray(e.standards)||!Array.isArray(e.aliases))return!1;let r=e.standards.every(s=>{if(typeof s!="object"||s===null)return!1;let i=s;return typeof i.standard_slug=="string"&&(i.catalog_record_id===null||typeof i.catalog_record_id=="string")}),n=e.aliases.every(s=>{if(typeof s!="object"||s===null)return!1;let i=s;return typeof i.alias=="string"&&(i.standard_slug===null||typeof i.standard_slug=="string")&&typeof i.evidence=="string"&&zx.has(i.evidence)});return r&&n}function Qx(t){let e=yr(en(t,o_)),r={etag:typeof e?.model_list?.etag=="string"?e.model_list.etag:null,last_checked:typeof e?.model_list?.last_checked=="string"?e.model_list.last_checked:null},n={etag:typeof e?.aliases?.etag=="string"?e.aliases.etag:null,last_checked:typeof e?.aliases?.last_checked=="string"?e.aliases.last_checked:null};if(e===null){let s=yr(en(t,Yx));s&&(r.etag=typeof s.etag=="string"?s.etag:null,r.last_checked=typeof s.fetchedAt=="string"?s.fetchedAt:null)}return{model_list:r,aliases:n}}function Zx(t){let e=Qx(t),r=yr(en(t,Ec)),n=yr(en(t,Tc));return{catalog:Vi(r)?r:null,aliases:Ki(n)?n:null,meta:e}}function eR(t,e){try{n_(t,{recursive:!0}),a_(en(t,o_),JSON.stringify(e))}catch{}}function zg(t,e,r){try{n_(t,{recursive:!0}),a_(en(t,e),JSON.stringify(r))}catch{}}function tR(t,e){let r=rR(t),n=r?[Ji(r,"data",e)]:[Ji(t,"..","..","data",e)];for(let s of n)if(s_(s))return s;return null}function rR(t){let e=Ji(t);for(;;){if(s_(Ji(e,"package.json")))return e;let r=i_(e);if(r===e)return null;e=r}}function Qg(t,e,r){let n=r!==void 0?r:tR(t,e);return n===null?null:yr(n)}function nR(){let t=process.env.LMCTL_PRICE_TTL;if(t===void 0||t==="")return Yg;let e=Number(t);return!Number.isFinite(e)||e<0?Yg:e*1e3}function sR(){let t=process.env.LMCTL_PRICE_DATA;return t!==void 0&&t!==""?t:null}async function Zg(t,e,r,n){try{let s=await t(e,{method:"HEAD",signal:AbortSignal.timeout(Jx)});if(!s.ok)return{kind:"failed"};let i=s.headers.get("etag");if(r!==null&&i!==null&&i===n)return{kind:"match"};let o=await t(e,{signal:AbortSignal.timeout(Vx)});return o.ok?{kind:"payload",payload:await o.json(),etag:o.headers.get("etag")??i}:{kind:"failed"}}catch{return{kind:"failed"}}}function Yi(t={}){return Object.keys(t).length===0?(e_??=t_(t),e_):t_(t)}async function t_(t){let e=i_(Xx(import.meta.url)),r=t.pinDir!==void 0?t.pinDir:sR();if(r!==null&&r!==""){let g=yr(Gi(r,Ec)),h=yr(Gi(r,Tc));if(Vi(g)&&Ki(h)){let _={catalog:g,aliases:h,source:"pinned",generatedAt:g.generated_at??null};return wc=_.generatedAt,_}return r_(t,e)}let n=t.fetchImpl??fetch,s=t.cacheDir??Kx(),i=t.now??Date.now(),o=t.ttlMs??nR(),a=Zx(s),l=(g,h)=>g!==null&&h.last_checked!==null&&i-Date.parse(h.last_checked)<o,c=a.catalog,u=a.aliases,d=!1,f={model_list:{...a.meta.model_list},aliases:{...a.meta.aliases}},m=!1;if(!l(c,a.meta.model_list)){let g=await Zg(n,qx,c,a.meta.model_list.etag);g.kind==="match"?(f.model_list.last_checked=new Date(i).toISOString(),m=!0):g.kind==="payload"&&(f.model_list.last_checked=new Date(i).toISOString(),m=!0,Vi(g.payload)&&(c=g.payload,g.etag!==null&&(f.model_list.etag=g.etag),zg(s,Ec,c),d=!0))}if(!l(u,a.meta.aliases)){let g=await Zg(n,Gx,u,a.meta.aliases.etag);g.kind==="match"?(f.aliases.last_checked=new Date(i).toISOString(),m=!0):g.kind==="payload"&&(f.aliases.last_checked=new Date(i).toISOString(),m=!0,Ki(g.payload)&&(u=g.payload,g.etag!==null&&(f.aliases.etag=g.etag),zg(s,Tc,u),d=!0))}if((m||d)&&eR(s,f),c!==null||u!==null){let g={catalog:c,aliases:u,source:d?"network":"cache",generatedAt:c?.generated_at??null};return wc=g.generatedAt,g}return r_(t,e)}function r_(t,e){let r=Qg(e,"price-data.json",t.bundledPath),n=Qg(e,"price-aliases.json",t.bundledAliasesPath),s=Vi(r)?r:null,i=Ki(n)?n:null,o={catalog:s,aliases:i,source:s!==null||i!==null?"bundled":"unavailable",generatedAt:s?.generated_at??null};return wc=o.generatedAt,o}function l_(t,e){if(e===null)return null;let{input_per_1m_tokens:r,output_per_1m_tokens:n,input_cache_read_per_1m_tokens:s}=e;if(r===null||n===null)return null;let i=s??r,o=t.input/1e6*r+t.output/1e6*n+t.cachedInput/1e6*i;return Number(o.toPrecision(10))}var qx,Gx,Jx,Vx,Yg,Ec,Tc,o_,Yx,zx,wc,e_,vc=k(()=>{"use strict";qx="https://lmctl.com/dataset/model_list.json",Gx="https://lmctl.com/dataset/aliases.json",Jx=1e3,Vx=1e4,Yg=6*60*60*1e3;Ec="model_list.json",Tc="aliases.json",o_="meta.json",Yx="model_list.meta.json";zx=new Set(["established","asserted","unresolved"]);wc=null,e_=null});function ss(t){return t.toLowerCase().replace(/(\d)\.(\d)/g,"$1-$2")}function Er(t){let e=t.source_model_id.toLowerCase(),r=e.slice(e.lastIndexOf("/")+1);return ss(r)}function d_(t){let e=new Set,r=n=>{let s=n.toLowerCase().split("/");for(let i=0;i<s.length;i+=1)e.add(ss(s.slice(i).join("/")))};return r(t.source_model_id),t.gateway_id&&r(t.gateway_id),e}function iR(t,e){let r=new Set,n=l=>{r.add(ss(l))},s=t.trim().toLowerCase(),i=null,o=s.indexOf(":");o>0&&!s.slice(0,o).includes("/")&&(i=s.slice(0,o),n(s),s=s.slice(o+1)),n(s);let a=s.slice(s.lastIndexOf("/")+1);n(a);for(let l of e)n(`${l}/${a}`);return i!==null&&n(`${i}/${a}`),[...r]}function tn(t){let e=n=>!(n.mode!==void 0&&n.mode!==null&&n.mode!=="chat"||t.nonChatName&&t.nonChatName.test(n.source_model_id.toLowerCase())),r=n=>e(n)&&t.family.test(n.source_model_id.toLowerCase());return{firstPartyProviders:t.firstPartyProviders,isChatModel:e,coversRecord:r,normalize:n=>iR(n,t.vendorPrefixes),matchRow(n,s){if(!r(n))return!1;let i=d_(n);return s.some(o=>i.has(o))}}}function aR(t){let e=t.trim(),r=oR.exec(e);return r?{model:e.slice(0,r.index).trim(),effort:r[1].trim()}:{model:e,effort:null}}function zi(t){return t==="moonshot"?0:t==="litellm"?1:t==="openrouter"?2:t==="manual"?3:4}function uR(t){return{route:t.record_id??`${t.source}:${t.source_model_id}`,source:t.source,sourceModelId:t.source_model_id,provider:t.provider??null,pricing:t.pricing,estimated:t.source==="manual"}}function __(t,e){return t.map(uR).sort((r,n)=>{let s=zi(r.source)-zi(n.source);if(s!==0)return s;let i=r.provider!==null&&e.includes(r.provider)?0:1,o=n.provider!==null&&e.includes(n.provider)?0:1;return i!==o?i-o:r.sourceModelId.localeCompare(n.sourceModelId)})}function Sc(t){return t.pricing.input_per_1m_tokens!==null&&t.pricing.output_per_1m_tokens!==null}function mR(t,e,r){let n=__(t,r),i=t.find(o=>(o.record_id??`${o.source}:${o.source_model_id}`)===n[0].route)?.context_window?.input_tokens??void 0;return{id:n[0].sourceModelId,normalizedId:e,offers:n,...i!=null?{contextWindow:i}:{}}}function bc(t,e,r){if(t.length===0)return{kind:"known-unpriced",id:e};let n=mR(t,e,r),s=n.offers.find(Sc);return s===void 0?{kind:"known-unpriced",id:e}:s.estimated?{kind:"estimated",model:n}:{kind:"priced",model:n}}function fR(t,e){return t.standards.find(r=>r.standard_slug.toLowerCase()===e.toLowerCase())??null}function pR(t,e,r){let n=t.standard_slug;if(e===null||e.catalog_record_id===null)return{kind:"known-unpriced",id:n};let s=e.catalog_record_id.toLowerCase(),i=r.records.find(l=>(l.record_id??`${l.source}:${l.source_model_id}`).toLowerCase()===s);if(!i)return{kind:"known-unpriced",id:n};let o=Er(i),a=r.records.filter(l=>Er(l)!==o?!1:l.mode===void 0||l.mode===null||l.mode==="chat");return a.length===0?{kind:"known-unpriced",id:n}:bc(a,o,Ic)}function y_(t,e,r,n){if(r===null||!Array.isArray(r.records))return{state:{kind:"no-catalog"},viaAlias:!1,pinRoute:null};if(n!==null){let h=[e.trim().toLowerCase()];h.push(`${t.toLowerCase()}/${h[0]}`);let _=n.aliases.find(p=>h.includes(p.alias.toLowerCase()));if(_){if(_.evidence==="unresolved"||_.standard_slug===null)return{state:{kind:"unresolved",alias:_.alias},viaAlias:!0,pinRoute:null};let p=fR(n,_.standard_slug);return{state:pR(_,p,r),viaAlias:!0,pinRoute:p?.catalog_record_id?.toLowerCase()??null}}}let s=Qi[t];if(!s)return{state:{kind:"no-catalog"},viaAlias:!1,pinRoute:null};let i=e.trim().toLowerCase(),o=s.normalize(e),a=h=>({state:h,viaAlias:!1,pinRoute:null}),l=ss(i),c=r.records.filter(h=>h.source_model_id.toLowerCase()===i&&s.matchRow(h,[l]));if(c.length>0){let h=Er(c[0]),_=r.records.filter(p=>s.matchRow(p,[h])&&Er(p)===h);return a(bc(_.length>0?_:c,h,c_[t]??Ic))}let u=r.records.filter(h=>s.matchRow(h,o));if(u.length===0)return a({kind:"unknown",declared:e});let d=new Map;for(let h of u){let _=Er(h),p=d.get(_);p?p.push(h):d.set(_,[h])}let f=c_[t]??Ic,m=null,g=null;for(let h of d.values()){let _=__(h,f);(g===null||hR(_[0],g[0],f)<0)&&(m=h,g=_)}return a(bc(m,Er(m[0]),f))}function Zi(t,e,r,n){return y_(t,e,r,n).state}function E_(t,e,r,n){let{state:s,viaAlias:i,pinRoute:o}=y_(t,e,r,n);if(s.kind!=="priced"&&s.kind!=="estimated")return{state:s,offer:null,provenance:null};let a=s.model.offers;if(i&&o!==null){let c=a.find(u=>u.route.toLowerCase()===o);if(c!==void 0&&Sc(c))return{state:s,offer:c,provenance:"alias-pin"}}let l=a.find(Sc)??null;return{state:s,offer:l,provenance:i&&o!==null?"alias-pin":"route-preference"}}function T_(t,e){let r=Qi[e];if(!r)return null;let n=new Set;for(let s of t.records)r.coversRecord(s)&&n.add(Er(s));return n.size}function hR(t,e,r){let n=zi(t.source)-zi(e.source);if(n!==0)return n;let s=t.provider!==null&&r.includes(t.provider)?0:1,i=e.provider!==null&&r.includes(e.provider)?0:1;return s!==i?s-i:t.sourceModelId.localeCompare(e.sourceModelId)}var u_,m_,f_,p_,h_,g_,oR,lR,cR,dR,Qi,c_,Ic,Ac=k(()=>{"use strict";u_=tn({vendorPrefixes:["anthropic"],family:/claude/,firstPartyProviders:["anthropic"]}),m_=tn({vendorPrefixes:["openai"],family:/(^|\/)(gpt-|o\d|chatgpt|ft:gpt)|openai\//,firstPartyProviders:["openai"],nonChatName:/(^|[-/])(tts|transcribe(?:-\w+)?|realtime(?:-\w+)?|search(?:-\w+)*|image(?:-\w+)?|audio(?:-\w+)?|whisper(?:-\w+)?|dall-e(?:-\w+)?|embedding|moderation)(-|$)/}),f_=tn({vendorPrefixes:["google","gemini"],family:/gemini|gemma/,firstPartyProviders:["gemini","google","vertex_ai-language-models"],nonChatName:/embedding|imagen|-image|tts|audio|veo|lyria|live|realtime|video/}),p_=tn({vendorPrefixes:["moonshot","moonshotai"],family:/kimi|moonshot/,firstPartyProviders:["moonshot"]}),h_=tn({vendorPrefixes:["dashscope","qwen"],family:/qwen/,firstPartyProviders:["dashscope"]}),g_=tn({vendorPrefixes:["deepseek","nousresearch"],family:/deepseek|nous|hermes-\d/,firstPartyProviders:["deepseek","nousresearch"]}),oR=/\s*\(([^()]+)\)\s*$/;lR={"gemini 3.8 flash":"gemini-3.8-flash","gemini 3.7 flash":"gemini-3.7-flash","gemini 3.6 flash":"gemini-3.6-flash","gemini 3.1 pro":"gemini/gemini-3.1-pro-preview","claude sonnet 4.6":"claude-sonnet-4-6"},cR=["gemini","google","vertex_ai-language-models","anthropic"],dR={normalize(t){let{model:e}=aR(t),r=lR[e.toLowerCase()];return r===void 0?[]:[ss(r)]},isChatModel(){return!0},coversRecord(t){return/gemini|claude/.test(t.source_model_id.toLowerCase())},matchRow(t,e){if(!this.coversRecord(t))return!1;let r=d_(t);return e.some(n=>r.has(n))}},Qi={claude:u_,codex:m_,gemini:f_,agy:dR,kimi:p_,qwen:h_,hermes:g_},c_={claude:u_.firstPartyProviders,codex:m_.firstPartyProviders,gemini:f_.firstPartyProviders,agy:cR,kimi:p_.firstPartyProviders,qwen:h_.firstPartyProviders,hermes:g_.firstPartyProviders};Ic=[]});var w_={};me(w_,{runCost:()=>TR});function _R(t,e,r,n){let s=new Set,i=[];for(let o of e){let a=r===null?null:Zi(t,o,r,n),l=a?.kind==="priced"||a?.kind==="estimated"?`id:${a.model.normalizedId}`:a?.kind==="known-unpriced"?`id:${a.id}`:`raw:${o.trim().toLowerCase()}`;s.has(l)||(s.add(l),i.push(o))}return i}async function TR(t,e={stdout:process.stdout,stderr:process.stderr}){if(t.includes("--help")||t.includes("-h"))return e.stdout.write(`${ER}
2325
2325
  `),0;let r=ie(t,["--provider"],["--json"]);if(r.error!==void 0)return x(e,r.error);if(r.positionals.length>2)return x(e,`too many positionals (${r.positionals.length}); expected <target> [alias]`);let n=H(r,"--json"),s=st(gR,{target:r.positionals[0],alias:r.positionals[1],flags:{provider:B(r,"--provider")}});if(s.mode==="error")return x(e,s.message);if(s.mode==="managed")return x(e,"cost: managed-run targets are not supported (no per-run token/model rollup exists)");let i,o;if(s.mode==="ai-team")try{let I=await C(e,R=>de(s.teamfile,s.alias,R));i=I.provider,o=I.sessionid}catch(I){if(I instanceof se)return x(e,I.message);throw I}else if(o=s.sessionid,s.provider!==void 0)i=s.provider;else{let I=await Yr(o);if(I.length===0)return x(e,`cost: session "${o}" not found in any provider store`);if(I.length>1)return x(e,`cost: session "${o}" matches multiple providers (${I.join(", ")}); pass --provider`);i=I[0]}let a;try{a=await $e(o,i)}catch(I){return x(e,`cost: failed to load session: ${I instanceof Error?I.message:String(I)}`)}if(a===null)return x(e,`cost: session not found: ${o} (provider=${i})`);let l=[...new Set(a.messages.map(I=>I.model).filter(I=>I!==void 0&&I!=="<synthetic>"))],c=[...a.messages].reverse().find(I=>I.model!==void 0&&I.model!=="<synthetic>")?.model,u=a.model??c??null,d={input:a.totalInputTokens??null,output:a.totalOutputTokens??null,cachedInput:a.totalCachedInputTokens??null},f=await Yi(),m=_R(i,l,f.catalog,f.aliases),g=m.length>1,h="unavailable",_=null,p=null,y=null,E=null,S=!1,v=null,T=null;if(u!==null&&f.catalog!==null){let I=E_(i,u,f.catalog,f.aliases);if(h=I.state.kind,I.offer!==null)T=I.offer.pricing,_=I.offer.route,p=I.offer.source,y=I.offer.sourceModelId,E=I.provenance,S=I.offer.estimated;else switch(I.state.kind){case"unresolved":v=`alias "${I.state.alias}" is deliberately unresolved in the lmprice alias table`;break;case"known-unpriced":v=`"${I.state.id}" is a known model with no published price row`;break;case"unknown":v=`model "${u}" not found in lmprice catalog for provider "${i}"`;break;default:v=`no lmprice catalog coverage for provider "${i}"`;break}}else u!==null&&(v="lmprice catalog unavailable");let b=T===null?null:{inputPer1m:T.input_per_1m_tokens,outputPer1m:T.output_per_1m_tokens,cachedInputPer1m:T.input_cache_read_per_1m_tokens},w=d.input===null||d.output===null?null:l_({input:d.input,output:d.output,cachedInput:d.cachedInput??0},T),A={schema_version:yR,provider:i,sessionId:o,model:u,modelsUsed:m,approximate:g,tokens:d,pricePerModel:b,costUsd:w,priceResolution:h,priceRoute:_,priceSource:p,priceSourceModelId:y,priceProvenance:E,priceEstimated:S,costUnavailableReason:v,priceDataSource:f.source,priceDataGeneratedAt:f.generatedAt};return n?(te(e,A),0):(e.stdout.write(`Session: ${o}
2326
2326
  `),e.stdout.write(` Provider: ${i}
2327
2327
  `),e.stdout.write(` Model: ${u??"(unknown)"}
@@ -220,13 +220,27 @@ gpt-oss-120b-medium GPT-OSS 120B (Medium)
220
220
 
221
221
  Every effort-tier variant of one base model maps to that base model's own catalog identity —
222
222
  reasoning effort/thinking budget changes how many tokens a turn generates, not the per-token rate,
223
- true of every major vendor's reasoning-effort parameter (OpenAI, Claude, Gemini alike). **Not yet
224
- mapped:** the 3 non-Gemini agy models (`Claude Sonnet 4.6 (Thinking)`, `Claude Opus 4.6 (Thinking)`,
225
- `GPT-OSS 120B (Medium)`) — smaller population, deferred, not the highest-value row. `claude opus 4.6
226
- (thinking)` already has an established display-label alias in lmprice's table (like the 4 Gemini
227
- ones above); `claude sonnet 4.6 (thinking)` and `gpt-oss 120b (medium)` don't — lmprice's alias table
228
- has a DASHED-slug entry for claude-sonnet-4-6 but under a spelling (`agy/claude-sonnet-4-6`) that
229
- doesn't match what agy actually declares (`Claude Sonnet 4.6 (Thinking)`), so it's a live gap too.
223
+ true of every major vendor's reasoning-effort parameter (OpenAI, Claude, Gemini alike).
224
+
225
+ **agy fronts Claude too, not just Gemini (math.lmctl, 2026-09-29):** 3 members declare `Claude Opus
226
+ 4.6 (Thinking)` on `provider=agy`. `coversRecord`/`AGY_FIRST_PARTY_PROVIDERS` were Gemini-only when
227
+ this was first written -- a real gap for Claude-on-agy, caught before it silently priced at zero.
228
+ Verified per-string, live:
229
+
230
+ - `claude opus 4.6 (thinking)` already had an established display-label alias in lmprice's table
231
+ (like the 4 Gemini ones above, added 2026-09-24) -- resolves via `alias-pin`, never touches
232
+ `AGY_MODEL_TO_IDENTITY` at all. No code change needed for this one specifically.
233
+ - `claude sonnet 4.6 (thinking)` had NO such alias and was a genuine `unknown` -- fixed by adding
234
+ `"claude sonnet 4.6": "claude-sonnet-4-6"` to `AGY_MODEL_TO_IDENTITY`, broadening `coversRecord` to
235
+ `/gemini|claude/`, and adding `"anthropic"` to `AGY_FIRST_PARTY_PROVIDERS` so the bare
236
+ `litellm:claude-sonnet-4-6` (provider `anthropic`) row wins the tie-break over routed variants
237
+ (`azure_ai/`, `deepinfra/`, `vertex_ai/`, `snowflake/`, `perplexity/`, `openrouter/`).
238
+ - `gpt-oss 120b (medium)` remains **deliberately unmapped**: unlike Claude/Gemini, OpenAI does not
239
+ host this open-weight model itself, so there is no single first-party row to prefer among a dozen
240
+ equally-plausible third-party inference providers (groq, fireworks_ai, cerebras, deepinfra, ...).
241
+ Picking one without evidence of which route agy actually uses would be exactly the kind of guess
242
+ this whole explicit-mapping design exists to avoid -- stays `unknown` until there's real evidence
243
+ (e.g. an antigravity.google/docs/models entry, same provenance as the existing aliases).
230
244
 
231
245
  ## OpenCode
232
246
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lmctl-ai/lmctl",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "A provider-agnostic control plane for teams of AI coding agents — across providers, with independent review and durable memory.",
5
5
  "type": "module",
6
6
  "homepage": "https://lmctl.com",