headroom-ai 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts","../src/client.ts","../src/utils/format.ts","../src/compress.ts"],"names":[],"mappings":";;;AA2FO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EACvC,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AACF;AAEO,IAAM,uBAAA,GAAN,cAAsC,aAAA,CAAc;AAAA,EACzD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,yBAAA;AAAA,EACd;AACF;AAEO,IAAM,iBAAA,GAAN,cAAgC,aAAA,CAAc;AAAA,EACnD,YAAY,OAAA,EAAiB;AAC3B,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,mBAAA;AAAA,EACd;AACF;AAEO,IAAM,qBAAA,GAAN,cAAoC,aAAA,CAAc;AAAA,EACvD,UAAA;AAAA,EACA,SAAA;AAAA,EAEA,WAAA,CAAY,UAAA,EAAoB,SAAA,EAAmB,OAAA,EAAiB;AAClE,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,uBAAA;AACZ,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF;;;AC5GA,IAAM,gBAAA,GAAmB,uBAAA;AACzB,IAAM,eAAA,GAAkB,GAAA;AACxB,IAAM,eAAA,GAAkB,CAAA;AAExB,SAAS,OAAO,GAAA,EAAiC;AAC/C,EAAA,IAAI,OAAO,OAAA,KAAY,WAAA,IAAe,OAAA,CAAQ,GAAA,EAAK;AACjD,IAAA,OAAO,OAAA,CAAQ,IAAI,GAAG,CAAA;AAAA,EACxB;AACA,EAAA,OAAO,MAAA;AACT;AAEA,SAAS,mBAAmB,QAAA,EAA2C;AACrE,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,YAAA,EAAc,CAAA;AAAA,IACd,WAAA,EAAa,CAAA;AAAA,IACb,WAAA,EAAa,CAAA;AAAA,IACb,gBAAA,EAAkB,CAAA;AAAA,IAClB,mBAAmB,EAAC;AAAA,IACpB,WAAW,EAAC;AAAA,IACZ,UAAA,EAAY;AAAA,GACd;AACF;AAEO,IAAM,iBAAN,MAAwD;AAAA,EACrD,OAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAiC,EAAC,EAAG;AAC/C,IAAA,IAAA,CAAK,OAAA,GAAA,CACH,QAAQ,OAAA,IACR,MAAA,CAAO,mBAAmB,CAAA,IAC1B,gBAAA,EACA,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AACpB,IAAA,IAAA,CAAK,MAAA,GAAS,OAAA,CAAQ,MAAA,IAAU,MAAA,CAAO,kBAAkB,CAAA;AACzD,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,eAAA;AAClC,IAAA,IAAA,CAAK,QAAA,GAAW,QAAQ,QAAA,IAAY,IAAA;AACpC,IAAA,IAAA,CAAK,OAAA,GAAU,QAAQ,OAAA,IAAW,eAAA;AAAA,EACpC;AAAA,EAEA,MAAM,QAAA,CACJ,QAAA,EACA,OAAA,GAA8B,EAAC,EACN;AACzB,IAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,QAAA;AAE/B,IAAA,IAAI,SAAA;AACJ,IAAA,MAAM,WAAA,GAAc,IAAI,IAAA,CAAK,OAAA;AAE7B,IAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,GAAU,WAAA,EAAa,OAAA,EAAA,EAAW;AACtD,MAAA,IAAI;AACF,QAAA,OAAO,MAAM,IAAA,CAAK,WAAA,CAAY,QAAA,EAAU,KAAK,CAAA;AAAA,MAC/C,SAAS,KAAA,EAAO;AACd,QAAA,SAAA,GAAY,KAAA;AAEZ,QAAA,IAAI,KAAA,YAAiB,mBAAmB,MAAM,KAAA;AAC9C,QAAA,IACE,KAAA,YAAiB,qBAAA,IACjB,KAAA,CAAM,UAAA,GAAa,GAAA,EACnB;AACA,UAAA,MAAM,KAAA;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AAGA,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,OAAO,mBAAmB,QAAQ,CAAA;AAAA,IACpC;AACA,IAAA,IAAI,SAAA,YAAqB,yBAAyB,MAAM,SAAA;AACxD,IAAA,IAAI,SAAA,YAAqB,uBAAuB,MAAM,SAAA;AACtD,IAAA,MAAM,IAAI,uBAAA;AAAA,MACR,CAAA,aAAA,EAAgB,WAAW,CAAA,WAAA,EAAc,SAAS,CAAA;AAAA,KACpD;AAAA,EACF;AAAA,EAEA,MAAc,WAAA,CACZ,QAAA,EACA,KAAA,EACyB;AACzB,IAAA,MAAM,GAAA,GAAM,CAAA,EAAG,IAAA,CAAK,OAAO,CAAA,YAAA,CAAA;AAC3B,IAAA,MAAM,OAAA,GAAkC;AAAA,MACtC,cAAA,EAAgB;AAAA,KAClB;AACA,IAAA,IAAI,KAAK,MAAA,EAAQ;AACf,MAAA,OAAA,CAAQ,eAAe,CAAA,GAAI,CAAA,OAAA,EAAU,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,IAClD;AAEA,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI;AACF,MAAA,QAAA,GAAW,MAAM,MAAM,GAAA,EAAK;AAAA,QAC1B,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA;AAAA,QACA,MAAM,IAAA,CAAK,SAAA,CAAU,EAAE,QAAA,EAAU,OAAO,CAAA;AAAA,QACxC,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,IAAA,CAAK,OAAO;AAAA,OACzC,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,uBAAA;AAAA,QACR,CAAA,iCAAA,EAAoC,IAAA,CAAK,OAAO,CAAA,EAAA,EAAK,KAAK,CAAA;AAAA,OAC5D;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI;AACF,QAAA,SAAA,GAAa,MAAM,SAAS,IAAA,EAAK;AAAA,MACnC,CAAA,CAAA,MAAQ;AAAA,MAER;AACA,MAAA,MAAM,SAAA,GAAY,SAAA,EAAW,KAAA,EAAO,IAAA,IAAQ,SAAA;AAC5C,MAAA,MAAM,eACJ,SAAA,EAAW,KAAA,EAAO,OAAA,IAAW,CAAA,KAAA,EAAQ,SAAS,MAAM,CAAA,CAAA;AAEtD,MAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,QAAA,MAAM,IAAI,kBAAkB,YAAY,CAAA;AAAA,MAC1C;AACA,MAAA,MAAM,IAAI,qBAAA,CAAsB,QAAA,CAAS,MAAA,EAAQ,WAAW,YAAY,CAAA;AAAA,IAC1E;AAEA,IAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAElC,IAAA,OAAO;AAAA,MACL,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,cAAc,IAAA,CAAK,aAAA;AAAA,MACnB,aAAa,IAAA,CAAK,YAAA;AAAA,MAClB,aAAa,IAAA,CAAK,YAAA;AAAA,MAClB,kBAAkB,IAAA,CAAK,iBAAA;AAAA,MACvB,mBAAmB,IAAA,CAAK,kBAAA;AAAA,MACxB,WAAW,IAAA,CAAK,UAAA;AAAA,MAChB,UAAA,EAAY;AAAA,KACd;AAAA,EACF;AACF;;;ACtHO,SAAS,aAAa,QAAA,EAAgC;AAC3D,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAE1B,IAAA,IAAI,OAAA,IAAW,GAAA,IAAO,EAAE,SAAA,IAAa,MAAM,OAAO,QAAA;AAGlD,IAAA,IAAI,GAAA,CAAI,IAAA,KAAS,OAAA,EAAS,OAAO,QAAA;AAGjC,IAAA,IAAI,GAAA,CAAI,UAAA,IAAc,GAAA,CAAI,IAAA,KAAS,aAAa,OAAO,QAAA;AAGvD,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,IAAU,cAAA,IAAkB,OAAO,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU,OAAO,QAAA;AAG5F,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,EAAG;AAC9B,MAAA,KAAA,MAAW,IAAA,IAAQ,IAAI,OAAA,EAAS;AAE9B,QAAA,IAAI,KAAK,IAAA,KAAS,WAAA,IAAe,IAAA,CAAK,IAAA,KAAS,eAAe,OAAO,QAAA;AAErE,QAAA,IAAI,KAAK,IAAA,KAAS,UAAA,IAAc,IAAA,CAAK,IAAA,KAAS,eAAe,OAAO,WAAA;AAEpE,QAAA,IAAI,KAAK,IAAA,KAAS,OAAA,IAAW,IAAA,CAAK,MAAA,EAAQ,MAAM,OAAO,WAAA;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAGA,EAAA,OAAO,QAAA;AACT;AAYO,SAAS,kBAAkB,QAAA,EAAkC;AAClE,EAAA,MAAM,SAA0B,EAAC;AAEjC,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU;AACnC,QAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,QAAQ,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AAClD,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,EAAG;AAC9B,QAAA,MAAM,UAAA,GAAa,IAAI,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,MAAM,CAAA;AACnE,QAAA,MAAM,WAAA,GAAc,IAAI,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,aAAa,CAAA;AAE3E,QAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,IAAA,EAAM,MAAA;AAAA,YACN,OAAA,EAAS,WAAW,GAAA,CAAI,CAAC,MAAW,CAAA,CAAE,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI;AAAA,WACtD,CAAA;AAAA,QACH;AACA,QAAA,KAAA,MAAW,MAAM,WAAA,EAAa;AAC5B,UAAA,MAAM,OAAA,GAAU,OAAO,EAAA,CAAG,OAAA,KAAY,QAAA,GAClC,EAAA,CAAG,OAAA,GACH,KAAA,CAAM,OAAA,CAAQ,EAAA,CAAG,OAAO,CAAA,GACtB,GAAG,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAW,CAAA,CAAE,IAAA,IAAQ,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,GACjE,IAAA,CAAK,SAAA,CAAU,GAAG,OAAO,CAAA;AAC/B,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,IAAA,EAAM,MAAA;AAAA,YACN,OAAA;AAAA,YACA,cAAc,EAAA,CAAG;AAAA,WAClB,CAAA;AAAA,QACH;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,MAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU;AACnC,QAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,aAAa,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AACvD,QAAA;AAAA,MACF;AACA,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,EAAG;AAC9B,QAAA,MAAM,UAAA,GAAa,IAAI,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,MAAM,CAAA;AACnE,QAAA,MAAM,aAAA,GAAgB,IAAI,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,UAAU,CAAA;AAE1E,QAAA,MAAM,OAAA,GAAU,UAAA,CAAW,MAAA,GAAS,CAAA,GAChC,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAW,CAAA,CAAE,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,GAC5C,IAAA;AAEJ,QAAA,MAAM,SAAA,GAA8B,EAAE,IAAA,EAAM,WAAA,EAAa,OAAA,EAAQ;AACjE,QAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,UAAA,SAAA,CAAU,UAAA,GAAa,aAAA,CAAc,GAAA,CAAI,CAAC,CAAA,MAAsB;AAAA,YAC9D,IAAI,CAAA,CAAE,EAAA;AAAA,YACN,IAAA,EAAM,UAAA;AAAA,YACN,QAAA,EAAU;AAAA,cACR,MAAM,CAAA,CAAE,IAAA;AAAA,cACR,SAAA,EAAW,OAAO,CAAA,CAAE,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,GAAQ,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,KAAK;AAAA;AAC3E,WACF,CAAE,CAAA;AAAA,QACJ;AACA,QAAA,MAAA,CAAO,KAAK,SAAS,CAAA;AAAA,MACvB;AACA,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,kBAAkB,QAAA,EAAkC;AAClE,EAAA,MAAM,SAAgB,EAAC;AAEvB,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,IAAI,GAAA,CAAI,SAAS,QAAA,EAAU;AAEzB,MAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,QAAQ,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AAClD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU;AACnC,QAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,QAAQ,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AAAA,MACpD,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,EAAG;AACrC,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,IAAA,EAAM,MAAA;AAAA,UACN,OAAA,EAAS,IAAI,OAAA,CAAQ,GAAA;AAAA,YAAI,CAAC,CAAA,KACxB,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,MAAK,GAAI,EAAE,IAAA,EAAM,MAAA,EAAQ,MAAM,EAAA;AAAG;AAChF,SACD,CAAA;AAAA,MACH;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,MAAA,MAAM,SAAgB,EAAC;AACvB,MAAA,IAAI,GAAA,CAAI,OAAA,EAAS,MAAA,CAAO,IAAA,CAAK,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,GAAA,CAAI,OAAA,EAAS,CAAA;AAChE,MAAA,IAAI,IAAI,UAAA,EAAY;AAClB,QAAA,KAAA,MAAW,EAAA,IAAM,IAAI,UAAA,EAAY;AAC/B,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,IAAA,EAAM,UAAA;AAAA,YACN,IAAI,EAAA,CAAG,EAAA;AAAA,YACP,IAAA,EAAM,GAAG,QAAA,CAAS,IAAA;AAAA,YAClB,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,EAAA,CAAG,SAAS,SAAS;AAAA,WACxC,CAAA;AAAA,QACH;AAAA,MACF;AACA,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,WAAA;AAAA,QACN,OAAA,EAAS,MAAA,CAAO,MAAA,KAAW,CAAA,IAAK,MAAA,CAAO,CAAC,CAAA,CAAE,IAAA,KAAS,MAAA,GAAS,MAAA,CAAO,CAAC,CAAA,CAAE,IAAA,GAAO;AAAA,OAC9E,CAAA;AACD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,MAAA;AAAA,QACN,OAAA,EAAS;AAAA,UACP,EAAE,MAAM,aAAA,EAAe,WAAA,EAAa,IAAI,YAAA,EAAc,OAAA,EAAS,IAAI,OAAA;AAAQ;AAC7E,OACD,CAAA;AACD,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,eAAe,QAAA,EAAkC;AAC/D,EAAA,MAAM,SAA0B,EAAC;AAEjC,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,IAAI,GAAA,CAAI,SAAS,QAAA,EAAU;AACzB,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,QAAA,EAAU,SAAS,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,GAAW,IAAI,OAAA,GAAU,MAAA,CAAO,GAAA,CAAI,OAAO,GAAG,CAAA;AAC5G,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU;AACnC,QAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,QAAQ,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AAClD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,GAAI,GAAA,CAAI,UAAU,EAAC;AAC1D,MAAA,MAAM,YAAY,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,MAAM,CAAA;AAC5D,MAAA,MAAM,aAAa,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,OAAO,CAAA;AAE9D,MAAA,IAAI,UAAA,CAAW,MAAA,KAAW,CAAA,IAAK,SAAA,CAAU,SAAS,CAAA,EAAG;AACnD,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAW,EAAE,IAAI,CAAA,CAAE,IAAA,CAAK,EAAE,GAAG,CAAA;AAAA,MACnF,CAAA,MAAO;AACL,QAAA,MAAM,WAAA,GAAc,KAAA,CACjB,MAAA,CAAO,CAAC,MAAW,CAAA,CAAE,IAAA,KAAS,MAAA,IAAU,CAAA,CAAE,IAAA,KAAS,OAAO,CAAA,CAC1D,GAAA,CAAI,CAAC,CAAA,KAAW;AACf,UAAA,IAAI,CAAA,CAAE,SAAS,MAAA,EAAQ,OAAO,EAAE,IAAA,EAAM,MAAA,EAAiB,IAAA,EAAM,CAAA,CAAE,IAAA,EAAK;AACpE,UAAA,IAAI,CAAA,CAAE,SAAS,OAAA,EAAS;AACtB,YAAA,MAAM,GAAA,GAAM,CAAA,CAAE,KAAA,YAAiB,GAAA,GAAM,CAAA,CAAE,MAAM,QAAA,EAAS,GAAI,MAAA,CAAO,CAAA,CAAE,KAAK,CAAA;AACxE,YAAA,OAAO,EAAE,IAAA,EAAM,WAAA,EAAsB,SAAA,EAAW,EAAE,KAAI,EAAE;AAAA,UAC1D;AACA,UAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAiB,IAAA,EAAM,EAAA,EAAG;AAAA,QAC3C,CAAC,CAAA;AACH,QAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,aAAa,CAAA;AAAA,MACpD;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,MAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU;AACnC,QAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,aAAa,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AACvD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,GAAI,GAAA,CAAI,UAAU,EAAC;AAC1D,MAAA,MAAM,YAAY,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,MAAM,CAAA;AAC5D,MAAA,MAAM,gBAAgB,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,WAAW,CAAA;AAErE,MAAA,MAAM,OAAA,GAAU,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAW,CAAA,CAAE,IAAI,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA,GAAI,IAAA;AACpF,MAAA,MAAM,SAAA,GAA8B,EAAE,IAAA,EAAM,WAAA,EAAa,OAAA,EAAQ;AAEjE,MAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,QAAA,SAAA,CAAU,UAAA,GAAa,aAAA,CAAc,GAAA,CAAI,CAAC,CAAA,MAAsB;AAAA,UAC9D,IAAI,CAAA,CAAE,UAAA;AAAA,UACN,IAAA,EAAM,UAAA;AAAA;AAAA,UAEN,QAAA,EAAU,EAAE,IAAA,EAAM,CAAA,CAAE,QAAA,EAAU,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,IAAI,CAAA;AAAE,SAC7E,CAAE,CAAA;AAAA,MACJ;AACA,MAAA,MAAA,CAAO,KAAK,SAAS,CAAA;AACrB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,GAAI,GAAA,CAAI,UAAU,EAAC;AAC1D,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,IAAI,IAAA,CAAK,SAAS,aAAA,EAAe;AAE/B,UAAA,IAAI,UAAA;AACJ,UAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAW;AAE7B,YAAA,MAAM,GAAA,GAAM,IAAA,CAAK,MAAA,EAAQ,KAAA,IAAS,IAAA,CAAK,MAAA;AACvC,YAAA,UAAA,GAAa,OAAO,GAAA,KAAQ,QAAA,GAAW,GAAA,GAAM,IAAA,CAAK,UAAU,GAAG,CAAA;AAAA,UACjE,CAAA,MAAA,IAAW,IAAA,CAAK,MAAA,KAAW,MAAA,EAAW;AAEpC,YAAA,UAAA,GAAa,OAAO,KAAK,MAAA,KAAW,QAAA,GAAW,KAAK,MAAA,GAAS,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,MAAM,CAAA;AAAA,UACzF,CAAA,MAAO;AACL,YAAA,UAAA,GAAa,EAAA;AAAA,UACf;AACA,UAAA,MAAA,CAAO,IAAA,CAAK;AAAA,YACV,IAAA,EAAM,MAAA;AAAA,YACN,OAAA,EAAS,UAAA;AAAA,YACT,cAAc,IAAA,CAAK;AAAA,WACpB,CAAA;AAAA,QACH;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,eAAe,QAAA,EAAkC;AAC/D,EAAA,MAAM,SAAgB,EAAC;AAEvB,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,IAAI,GAAA,CAAI,SAAS,QAAA,EAAU;AACzB,MAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,UAAU,OAAA,EAAS,GAAA,CAAI,SAAS,CAAA;AACpD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,IAAI,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,EAAU;AACnC,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,CAAC,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,GAAA,CAAI,OAAA,EAAS,GAAG,CAAA;AAAA,MAC9E,CAAA,MAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,EAAG;AACrC,QAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAM;AACnC,UAAA,IAAI,CAAA,CAAE,SAAS,MAAA,EAAQ,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,CAAA,CAAE,IAAA,EAAK;AAC3D,UAAA,IAAI,CAAA,CAAE,IAAA,KAAS,WAAA,EAAa,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,IAAI,GAAA,CAAI,CAAA,CAAE,SAAA,CAAU,GAAG,CAAA,EAAE;AACpF,UAAA,OAAO,EAAE,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAM,EAAA,EAAG;AAAA,QAClC,CAAC,CAAA;AACD,QAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAA;AAAA,MAC9C;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,MAAA,MAAM,QAAe,EAAC;AACtB,MAAA,IAAI,GAAA,CAAI,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,EAAE,MAAM,MAAA,EAAQ,IAAA,EAAM,GAAA,CAAI,OAAA,EAAS,CAAA;AAC/D,MAAA,IAAI,IAAI,UAAA,EAAY;AAClB,QAAA,KAAA,MAAW,EAAA,IAAM,IAAI,UAAA,EAAY;AAC/B,UAAA,IAAI,KAAA;AACJ,UAAA,IAAI;AAAE,YAAA,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,EAAA,CAAG,QAAA,CAAS,SAAS,CAAA;AAAA,UAAG,CAAA,CAAA,MAAQ;AAAE,YAAA,KAAA,GAAQ,EAAA,CAAG,QAAA,CAAS,SAAA,IAAa,EAAC;AAAA,UAAG;AAChG,UAAA,KAAA,CAAM,IAAA,CAAK;AAAA,YACT,IAAA,EAAM,WAAA;AAAA,YACN,YAAY,EAAA,CAAG,EAAA;AAAA,YACf,QAAA,EAAU,GAAG,QAAA,CAAS,IAAA;AAAA,YACtB;AAAA;AAAA,WACD,CAAA;AAAA,QACH;AAAA,MACF;AACA,MAAA,MAAA,CAAO,KAAK,EAAE,IAAA,EAAM,WAAA,EAAa,OAAA,EAAS,OAAO,CAAA;AACjD,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,IAAI,MAAA;AACJ,MAAA,IAAI;AAAE,QAAA,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAE,QAAA,MAAA,GAAS,GAAA,CAAI,OAAA;AAAA,MAAS;AAExE,MAAA,MAAM,MAAA,GAAS,OAAO,MAAA,KAAW,QAAA,GAC7B,EAAE,IAAA,EAAM,MAAA,EAAiB,KAAA,EAAO,MAAA,EAAO,GACvC,EAAE,IAAA,EAAM,MAAA,EAAiB,OAAO,MAAA,EAAO;AAC3C,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,MAAA;AAAA,QACN,SAAS,CAAC;AAAA,UACR,IAAA,EAAM,aAAA;AAAA,UACN,YAAY,GAAA,CAAI,YAAA;AAAA,UAChB,QAAA,EAAU,SAAA;AAAA,UACV;AAAA,SACD;AAAA,OACF,CAAA;AACD,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,eAAe,QAAA,EAAkC;AAC/D,EAAA,MAAM,SAA0B,EAAC;AAEjC,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,MAAM,IAAA,GAAO,GAAA,CAAI,IAAA,KAAS,OAAA,GAAU,WAAA,GAAc,MAAA;AAClD,IAAA,MAAM,KAAA,GAAe,GAAA,CAAI,KAAA,IAAS,EAAC;AAEnC,IAAA,IAAI,SAAS,MAAA,EAAQ;AAEnB,MAAA,MAAM,gBAAgB,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAW,EAAE,gBAAgB,CAAA;AACjE,MAAA,MAAM,YAAY,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,MAAS,CAAA;AAE/D,MAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACxB,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAS,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAW,EAAE,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,GAAG,CAAA;AAAA,MACrF;AACA,MAAA,KAAA,MAAW,MAAM,aAAA,EAAe;AAC9B,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,IAAA,EAAM,MAAA;AAAA,UACN,OAAA,EAAS,IAAA,CAAK,SAAA,CAAU,EAAA,CAAG,iBAAiB,QAAQ,CAAA;AAAA,UACpD,YAAA,EAAc,CAAA,OAAA,EAAU,EAAA,CAAG,gBAAA,CAAiB,IAAI,CAAA;AAAA,SACjD,CAAA;AAAA,MACH;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,SAAS,WAAA,EAAa;AACxB,MAAA,MAAM,YAAY,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAW,CAAA,CAAE,SAAS,MAAS,CAAA;AAC/D,MAAA,MAAM,YAAY,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAW,EAAE,YAAY,CAAA;AAEzD,MAAA,MAAM,OAAA,GAAU,SAAA,CAAU,MAAA,GAAS,CAAA,GAAI,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAW,CAAA,CAAE,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AACtF,MAAA,MAAM,SAAA,GAA8B,EAAE,IAAA,EAAM,WAAA,EAAa,OAAA,EAAQ;AAEjE,MAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACxB,QAAA,SAAA,CAAU,UAAA,GAAa,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,MAAsB;AAAA,UAC1D,EAAA,EAAI,CAAA,OAAA,EAAU,CAAA,CAAE,YAAA,CAAa,IAAI,CAAA,CAAA;AAAA,UACjC,IAAA,EAAM,UAAA;AAAA,UACN,QAAA,EAAU;AAAA,YACR,IAAA,EAAM,EAAE,YAAA,CAAa,IAAA;AAAA,YACrB,SAAA,EAAW,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,aAAa,IAAI;AAAA;AAC/C,SACF,CAAE,CAAA;AAAA,MACJ;AACA,MAAA,MAAA,CAAO,KAAK,SAAS,CAAA;AACrB,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,eAAe,QAAA,EAAkC;AAC/D,EAAA,MAAM,SAAgB,EAAC;AAEvB,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,IAAI,GAAA,CAAI,SAAS,QAAA,EAAU;AAEzB,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,CAAC,EAAE,IAAA,EAAM,GAAA,CAAI,OAAA,EAAS,CAAA,EAAG,CAAA;AAC5D,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,MAAM,IAAA,GAAO,OAAO,GAAA,CAAI,OAAA,KAAY,QAAA,GAChC,IAAI,OAAA,GAAA,CACH,GAAA,CAAI,OAAA,IAAW,EAAC,EAAG,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,MAAM,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAO,CAAA,CAAU,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC9F,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,KAAA,EAAO,CAAC,EAAE,IAAA,EAAM,CAAA,EAAG,CAAA;AAC/C,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,WAAA,EAAa;AAC5B,MAAA,MAAM,QAAe,EAAC;AACtB,MAAA,IAAI,GAAA,CAAI,SAAS,KAAA,CAAM,IAAA,CAAK,EAAE,IAAA,EAAM,GAAA,CAAI,SAAS,CAAA;AACjD,MAAA,IAAI,IAAI,UAAA,EAAY;AAClB,QAAA,KAAA,MAAW,EAAA,IAAM,IAAI,UAAA,EAAY;AAC/B,UAAA,KAAA,CAAM,IAAA,CAAK;AAAA,YACT,YAAA,EAAc,EAAE,IAAA,EAAM,EAAA,CAAG,QAAA,CAAS,IAAA,EAAM,IAAA,EAAM,IAAA,CAAK,KAAA,CAAM,EAAA,CAAG,QAAA,CAAS,SAAS,CAAA;AAAE,WACjF,CAAA;AAAA,QACH;AAAA,MACF;AACA,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,OAAA,EAAS,OAAO,CAAA;AACpC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,GAAA,CAAI,SAAS,MAAA,EAAQ;AACvB,MAAA,IAAI,QAAA;AACJ,MAAA,IAAI;AAAE,QAAA,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AAAA,MAAG,CAAA,CAAA,MAAQ;AAAE,QAAA,QAAA,GAAW,EAAE,MAAA,EAAQ,GAAA,CAAI,OAAA,EAAQ;AAAA,MAAG;AACxF,MAAA,MAAA,CAAO,IAAA,CAAK;AAAA,QACV,IAAA,EAAM,MAAA;AAAA,QACN,KAAA,EAAO,CAAC,EAAE,gBAAA,EAAkB,EAAE,IAAA,EAAM,GAAA,CAAI,YAAA,EAAc,OAAA,CAAQ,WAAW,EAAE,CAAA,IAAK,SAAA,EAAW,QAAA,IAAY;AAAA,OACxG,CAAA;AACD,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,SAAS,QAAA,EAAkC;AACzD,EAAA,MAAM,MAAA,GAAS,aAAa,QAAQ,CAAA;AACpC,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,QAAA;AAAU,MAAA,OAAO,QAAA;AAAA,IACtB,KAAK,WAAA;AAAa,MAAA,OAAO,kBAAkB,QAAQ,CAAA;AAAA,IACnD,KAAK,QAAA;AAAU,MAAA,OAAO,eAAe,QAAQ,CAAA;AAAA,IAC7C,KAAK,QAAA;AAAU,MAAA,OAAO,eAAe,QAAQ,CAAA;AAAA;AAEjD;AAEO,SAAS,UAAA,CAAW,UAA2B,YAAA,EAAoC;AACxF,EAAA,QAAQ,YAAA;AAAc,IACpB,KAAK,QAAA;AAAU,MAAA,OAAO,QAAA;AAAA,IACtB,KAAK,WAAA;AAAa,MAAA,OAAO,kBAAkB,QAAQ,CAAA;AAAA,IACnD,KAAK,QAAA;AAAU,MAAA,OAAO,eAAe,QAAQ,CAAA;AAAA,IAC7C,KAAK,QAAA;AAAU,MAAA,OAAO,eAAe,QAAQ,CAAA;AAAA;AAEjD;;;ACpcA,eAAsB,QAAA,CACpB,QAAA,EACA,OAAA,GAA2B,EAAC,EACH;AACzB,EAAA,MAAM,EAAE,MAAA,EAAQ,cAAA,EAAgB,KAAA,EAAO,GAAG,eAAc,GAAI,OAAA;AAG5D,EAAA,MAAM,WAAA,GAAc,aAAa,QAAQ,CAAA;AAGzC,EAAA,MAAM,cAAA,GAAiB,SAAS,QAAQ,CAAA;AAGxC,EAAA,MAAM,MAAA,GAAS,cAAA,IAAkB,IAAI,cAAA,CAAe,aAAa,CAAA;AACjE,EAAA,MAAM,SAAS,MAAM,MAAA,CAAO,SAAS,cAAA,EAAgB,EAAE,OAAO,CAAA;AAG9D,EAAA,MAAM,cAAA,GAAiB,UAAA,CAAW,MAAA,CAAO,QAAA,EAAU,WAAW,CAAA;AAE9D,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,QAAA,EAAU;AAAA,GACZ;AACF","file":"chunk-3N25JEWK.cjs","sourcesContent":["// --- Message types (OpenAI chat format) ---\n\nexport interface TextContentPart {\n type: \"text\";\n text: string;\n}\n\nexport interface ImageContentPart {\n type: \"image_url\";\n image_url: { url: string; detail?: \"auto\" | \"low\" | \"high\" };\n}\n\nexport type ContentPart = TextContentPart | ImageContentPart;\n\nexport interface ToolCall {\n id: string;\n type: \"function\";\n function: { name: string; arguments: string };\n}\n\nexport interface SystemMessage {\n role: \"system\";\n content: string;\n}\n\nexport interface UserMessage {\n role: \"user\";\n content: string | ContentPart[];\n}\n\nexport interface AssistantMessage {\n role: \"assistant\";\n content: string | null;\n tool_calls?: ToolCall[];\n}\n\nexport interface ToolMessage {\n role: \"tool\";\n content: string;\n tool_call_id: string;\n}\n\nexport type OpenAIMessage =\n | SystemMessage\n | UserMessage\n | AssistantMessage\n | ToolMessage;\n\n// --- Compress API ---\n\nexport interface CompressOptions {\n model?: string;\n baseUrl?: string;\n apiKey?: string;\n timeout?: number;\n fallback?: boolean;\n retries?: number;\n client?: HeadroomClientInterface;\n}\n\nexport interface CompressResult {\n /** Compressed messages in the same format as input. */\n messages: any[];\n tokensBefore: number;\n tokensAfter: number;\n tokensSaved: number;\n compressionRatio: number;\n transformsApplied: string[];\n ccrHashes: string[];\n compressed: boolean;\n}\n\n// --- Client ---\n\nexport interface HeadroomClientOptions {\n baseUrl?: string;\n apiKey?: string;\n timeout?: number;\n fallback?: boolean;\n retries?: number;\n}\n\nexport interface HeadroomClientInterface {\n compress(\n messages: OpenAIMessage[],\n options?: { model?: string },\n ): Promise<CompressResult>;\n}\n\n// --- Errors ---\n\nexport class HeadroomError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"HeadroomError\";\n }\n}\n\nexport class HeadroomConnectionError extends HeadroomError {\n constructor(message: string) {\n super(message);\n this.name = \"HeadroomConnectionError\";\n }\n}\n\nexport class HeadroomAuthError extends HeadroomError {\n constructor(message: string) {\n super(message);\n this.name = \"HeadroomAuthError\";\n }\n}\n\nexport class HeadroomCompressError extends HeadroomError {\n statusCode: number;\n errorType: string;\n\n constructor(statusCode: number, errorType: string, message: string) {\n super(message);\n this.name = \"HeadroomCompressError\";\n this.statusCode = statusCode;\n this.errorType = errorType;\n }\n}\n\n// --- Proxy response (internal) ---\n\nexport interface ProxyCompressResponse {\n messages: OpenAIMessage[];\n tokens_before: number;\n tokens_after: number;\n tokens_saved: number;\n compression_ratio: number;\n transforms_applied: string[];\n ccr_hashes: string[];\n}\n\nexport interface ProxyErrorResponse {\n error: {\n type: string;\n message: string;\n };\n}\n","import type {\n OpenAIMessage,\n CompressResult,\n HeadroomClientOptions,\n HeadroomClientInterface,\n ProxyCompressResponse,\n ProxyErrorResponse,\n} from \"./types.js\";\nimport {\n HeadroomConnectionError,\n HeadroomAuthError,\n HeadroomCompressError,\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"http://localhost:8787\";\nconst DEFAULT_TIMEOUT = 30_000;\nconst DEFAULT_RETRIES = 1;\n\nfunction getEnv(key: string): string | undefined {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[key];\n }\n return undefined;\n}\n\nfunction makeFallbackResult(messages: OpenAIMessage[]): CompressResult {\n return {\n messages,\n tokensBefore: 0,\n tokensAfter: 0,\n tokensSaved: 0,\n compressionRatio: 1.0,\n transformsApplied: [],\n ccrHashes: [],\n compressed: false,\n };\n}\n\nexport class HeadroomClient implements HeadroomClientInterface {\n private baseUrl: string;\n private apiKey: string | undefined;\n private timeout: number;\n private fallback: boolean;\n private retries: number;\n\n constructor(options: HeadroomClientOptions = {}) {\n this.baseUrl = (\n options.baseUrl ??\n getEnv(\"HEADROOM_BASE_URL\") ??\n DEFAULT_BASE_URL\n ).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey ?? getEnv(\"HEADROOM_API_KEY\");\n this.timeout = options.timeout ?? DEFAULT_TIMEOUT;\n this.fallback = options.fallback ?? true;\n this.retries = options.retries ?? DEFAULT_RETRIES;\n }\n\n async compress(\n messages: OpenAIMessage[],\n options: { model?: string } = {},\n ): Promise<CompressResult> {\n const model = options.model ?? \"gpt-4o\";\n\n let lastError: unknown;\n const maxAttempts = 1 + this.retries;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await this._doCompress(messages, model);\n } catch (error) {\n lastError = error;\n // Don't retry auth errors or client errors\n if (error instanceof HeadroomAuthError) throw error;\n if (\n error instanceof HeadroomCompressError &&\n error.statusCode < 500\n ) {\n throw error;\n }\n // Retry on transient errors (network, 5xx)\n }\n }\n\n // All attempts exhausted\n if (this.fallback) {\n return makeFallbackResult(messages);\n }\n if (lastError instanceof HeadroomConnectionError) throw lastError;\n if (lastError instanceof HeadroomCompressError) throw lastError;\n throw new HeadroomConnectionError(\n `Failed after ${maxAttempts} attempts: ${lastError}`,\n );\n }\n\n private async _doCompress(\n messages: OpenAIMessage[],\n model: string,\n ): Promise<CompressResult> {\n const url = `${this.baseUrl}/v1/compress`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (this.apiKey) {\n headers[\"Authorization\"] = `Bearer ${this.apiKey}`;\n }\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ messages, model }),\n signal: AbortSignal.timeout(this.timeout),\n });\n } catch (error) {\n throw new HeadroomConnectionError(\n `Failed to connect to Headroom at ${this.baseUrl}: ${error}`,\n );\n }\n\n if (!response.ok) {\n let errorBody: ProxyErrorResponse | undefined;\n try {\n errorBody = (await response.json()) as ProxyErrorResponse;\n } catch {\n // ignore parse errors on error responses\n }\n const errorType = errorBody?.error?.type ?? \"unknown\";\n const errorMessage =\n errorBody?.error?.message ?? `HTTP ${response.status}`;\n\n if (response.status === 401) {\n throw new HeadroomAuthError(errorMessage);\n }\n throw new HeadroomCompressError(response.status, errorType, errorMessage);\n }\n\n const data = (await response.json()) as ProxyCompressResponse;\n\n return {\n messages: data.messages,\n tokensBefore: data.tokens_before,\n tokensAfter: data.tokens_after,\n tokensSaved: data.tokens_saved,\n compressionRatio: data.compression_ratio,\n transformsApplied: data.transforms_applied,\n ccrHashes: data.ccr_hashes,\n compressed: true,\n };\n }\n}\n","/**\n * Universal message format detection and conversion.\n *\n * Supports 4 formats:\n * - OpenAI: { role, content, tool_calls?, tool_call_id? }\n * - Anthropic: { role, content (string | ContentBlock[]) } with tool_use/tool_result blocks\n * - Vercel AI SDK: { role, content (string | Part[]) } with tool-call/tool-result parts\n * - Google Gemini: { role, parts[] } with functionCall/functionResponse\n *\n * Detection is structural (unique keys/values per format), not heuristic.\n * Conversion always targets OpenAI format (the proxy's lingua franca).\n */\n\nimport type {\n OpenAIMessage,\n AssistantMessage,\n ToolCall,\n} from \"../types.js\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport type MessageFormat = \"openai\" | \"anthropic\" | \"vercel\" | \"gemini\";\n\n/**\n * Detect which format an array of messages is in.\n *\n * Uses structural markers unique to each format:\n * - Gemini: messages have `parts` field (not `content`)\n * - Vercel: content parts use hyphenated types: `tool-call`, `tool-result`\n * - Anthropic: content blocks use underscored types: `tool_use`, `tool_result`\n * - OpenAI: assistant messages have `tool_calls` field; tool messages have `tool_call_id`\n */\nexport function detectFormat(messages: any[]): MessageFormat {\n for (const msg of messages) {\n // Gemini: uses `parts` instead of `content`\n if (\"parts\" in msg && !(\"content\" in msg)) return \"gemini\";\n\n // Gemini: role \"model\" instead of \"assistant\"\n if (msg.role === \"model\") return \"gemini\";\n\n // OpenAI: tool_calls on assistant messages\n if (msg.tool_calls && msg.role === \"assistant\") return \"openai\";\n\n // OpenAI: tool role with tool_call_id\n if (msg.role === \"tool\" && \"tool_call_id\" in msg && typeof msg.content === \"string\") return \"openai\";\n\n // Check content blocks/parts for format-specific markers\n if (Array.isArray(msg.content)) {\n for (const part of msg.content) {\n // Vercel: hyphenated types\n if (part.type === \"tool-call\" || part.type === \"tool-result\") return \"vercel\";\n // Anthropic: underscored types\n if (part.type === \"tool_use\" || part.type === \"tool_result\") return \"anthropic\";\n // Anthropic: image with source.type\n if (part.type === \"image\" && part.source?.type) return \"anthropic\";\n }\n }\n }\n\n // Default: OpenAI (simple {role, content: string} is valid OpenAI)\n return \"openai\";\n}\n\n// ============================================================\n// OpenAI ↔ OpenAI (passthrough)\n// ============================================================\n\n// No conversion needed — this is the canonical format.\n\n// ============================================================\n// Anthropic → OpenAI\n// ============================================================\n\nexport function anthropicToOpenAI(messages: any[]): OpenAIMessage[] {\n const result: OpenAIMessage[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"user\") {\n if (typeof msg.content === \"string\") {\n result.push({ role: \"user\", content: msg.content });\n continue;\n }\n if (Array.isArray(msg.content)) {\n const textBlocks = msg.content.filter((b: any) => b.type === \"text\");\n const toolResults = msg.content.filter((b: any) => b.type === \"tool_result\");\n\n if (textBlocks.length > 0) {\n result.push({\n role: \"user\",\n content: textBlocks.map((b: any) => b.text).join(\"\\n\"),\n });\n }\n for (const tr of toolResults) {\n const content = typeof tr.content === \"string\"\n ? tr.content\n : Array.isArray(tr.content)\n ? tr.content.map((b: any) => b.text ?? JSON.stringify(b)).join(\"\\n\")\n : JSON.stringify(tr.content);\n result.push({\n role: \"tool\",\n content,\n tool_call_id: tr.tool_use_id,\n });\n }\n }\n continue;\n }\n\n if (msg.role === \"assistant\") {\n if (typeof msg.content === \"string\") {\n result.push({ role: \"assistant\", content: msg.content });\n continue;\n }\n if (Array.isArray(msg.content)) {\n const textBlocks = msg.content.filter((b: any) => b.type === \"text\");\n const toolUseBlocks = msg.content.filter((b: any) => b.type === \"tool_use\");\n\n const content = textBlocks.length > 0\n ? textBlocks.map((b: any) => b.text).join(\"\\n\")\n : null;\n\n const openaiMsg: AssistantMessage = { role: \"assistant\", content };\n if (toolUseBlocks.length > 0) {\n openaiMsg.tool_calls = toolUseBlocks.map((b: any): ToolCall => ({\n id: b.id,\n type: \"function\",\n function: {\n name: b.name,\n arguments: typeof b.input === \"string\" ? b.input : JSON.stringify(b.input),\n },\n }));\n }\n result.push(openaiMsg);\n }\n continue;\n }\n }\n\n return result;\n}\n\nexport function openAIToAnthropic(messages: OpenAIMessage[]): any[] {\n const result: any[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") {\n // Anthropic system is top-level, but if it appears in messages, convert to user\n result.push({ role: \"user\", content: msg.content });\n continue;\n }\n\n if (msg.role === \"user\") {\n if (typeof msg.content === \"string\") {\n result.push({ role: \"user\", content: msg.content });\n } else if (Array.isArray(msg.content)) {\n result.push({\n role: \"user\",\n content: msg.content.map((p) =>\n p.type === \"text\" ? { type: \"text\", text: p.text } : { type: \"text\", text: \"\" },\n ),\n });\n }\n continue;\n }\n\n if (msg.role === \"assistant\") {\n const blocks: any[] = [];\n if (msg.content) blocks.push({ type: \"text\", text: msg.content });\n if (msg.tool_calls) {\n for (const tc of msg.tool_calls) {\n blocks.push({\n type: \"tool_use\",\n id: tc.id,\n name: tc.function.name,\n input: JSON.parse(tc.function.arguments),\n });\n }\n }\n result.push({\n role: \"assistant\",\n content: blocks.length === 1 && blocks[0].type === \"text\" ? blocks[0].text : blocks,\n });\n continue;\n }\n\n if (msg.role === \"tool\") {\n result.push({\n role: \"user\",\n content: [\n { type: \"tool_result\", tool_use_id: msg.tool_call_id, content: msg.content },\n ],\n });\n continue;\n }\n }\n\n return result;\n}\n\n// ============================================================\n// Vercel AI SDK → OpenAI\n// ============================================================\n\nexport function vercelToOpenAI(messages: any[]): OpenAIMessage[] {\n const result: OpenAIMessage[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") {\n result.push({ role: \"system\", content: typeof msg.content === \"string\" ? msg.content : String(msg.content) });\n continue;\n }\n\n if (msg.role === \"user\") {\n if (typeof msg.content === \"string\") {\n result.push({ role: \"user\", content: msg.content });\n continue;\n }\n const parts = Array.isArray(msg.content) ? msg.content : [];\n const textParts = parts.filter((p: any) => p.type === \"text\");\n const imageParts = parts.filter((p: any) => p.type === \"image\");\n\n if (imageParts.length === 0 && textParts.length > 0) {\n result.push({ role: \"user\", content: textParts.map((p: any) => p.text).join(\"\") });\n } else {\n const openaiParts = parts\n .filter((p: any) => p.type === \"text\" || p.type === \"image\")\n .map((p: any) => {\n if (p.type === \"text\") return { type: \"text\" as const, text: p.text };\n if (p.type === \"image\") {\n const url = p.image instanceof URL ? p.image.toString() : String(p.image);\n return { type: \"image_url\" as const, image_url: { url } };\n }\n return { type: \"text\" as const, text: \"\" };\n });\n result.push({ role: \"user\", content: openaiParts });\n }\n continue;\n }\n\n if (msg.role === \"assistant\") {\n if (typeof msg.content === \"string\") {\n result.push({ role: \"assistant\", content: msg.content });\n continue;\n }\n const parts = Array.isArray(msg.content) ? msg.content : [];\n const textParts = parts.filter((p: any) => p.type === \"text\");\n const toolCallParts = parts.filter((p: any) => p.type === \"tool-call\");\n\n const content = textParts.length > 0 ? textParts.map((p: any) => p.text).join(\"\") : null;\n const openaiMsg: AssistantMessage = { role: \"assistant\", content };\n\n if (toolCallParts.length > 0) {\n openaiMsg.tool_calls = toolCallParts.map((p: any): ToolCall => ({\n id: p.toolCallId,\n type: \"function\",\n // AI SDK v6 uses `input`, earlier versions used `args`\n function: { name: p.toolName, arguments: JSON.stringify(p.input ?? p.args) },\n }));\n }\n result.push(openaiMsg);\n continue;\n }\n\n if (msg.role === \"tool\") {\n const parts = Array.isArray(msg.content) ? msg.content : [];\n for (const part of parts) {\n if (part.type === \"tool-result\") {\n // AI SDK v6 uses `output: { type, value }`, earlier versions used `result`\n let contentStr: string;\n if (part.output !== undefined) {\n // v6 format: output is { type: 'json', value } or { type: 'text', value }\n const val = part.output?.value ?? part.output;\n contentStr = typeof val === \"string\" ? val : JSON.stringify(val);\n } else if (part.result !== undefined) {\n // Legacy format: result field directly\n contentStr = typeof part.result === \"string\" ? part.result : JSON.stringify(part.result);\n } else {\n contentStr = \"\";\n }\n result.push({\n role: \"tool\",\n content: contentStr,\n tool_call_id: part.toolCallId,\n });\n }\n }\n continue;\n }\n }\n\n return result;\n}\n\nexport function openAIToVercel(messages: OpenAIMessage[]): any[] {\n const result: any[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") {\n result.push({ role: \"system\", content: msg.content });\n continue;\n }\n\n if (msg.role === \"user\") {\n if (typeof msg.content === \"string\") {\n result.push({ role: \"user\", content: [{ type: \"text\", text: msg.content }] });\n } else if (Array.isArray(msg.content)) {\n const parts = msg.content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n if (p.type === \"image_url\") return { type: \"image\", image: new URL(p.image_url.url) };\n return { type: \"text\", text: \"\" };\n });\n result.push({ role: \"user\", content: parts });\n }\n continue;\n }\n\n if (msg.role === \"assistant\") {\n const parts: any[] = [];\n if (msg.content) parts.push({ type: \"text\", text: msg.content });\n if (msg.tool_calls) {\n for (const tc of msg.tool_calls) {\n let input: any;\n try { input = JSON.parse(tc.function.arguments); } catch { input = tc.function.arguments ?? {}; }\n parts.push({\n type: \"tool-call\",\n toolCallId: tc.id,\n toolName: tc.function.name,\n input, // AI SDK v6 uses `input`, not `args`\n });\n }\n }\n result.push({ role: \"assistant\", content: parts });\n continue;\n }\n\n if (msg.role === \"tool\") {\n let parsed: any;\n try { parsed = JSON.parse(msg.content); } catch { parsed = msg.content; }\n // AI SDK v6 requires output: { type: 'json' | 'text', value }\n const output = typeof parsed === \"string\"\n ? { type: \"text\" as const, value: parsed }\n : { type: \"json\" as const, value: parsed };\n result.push({\n role: \"tool\",\n content: [{\n type: \"tool-result\",\n toolCallId: msg.tool_call_id,\n toolName: \"unknown\",\n output,\n }],\n });\n continue;\n }\n }\n\n return result;\n}\n\n// ============================================================\n// Google Gemini → OpenAI\n// ============================================================\n\nexport function geminiToOpenAI(messages: any[]): OpenAIMessage[] {\n const result: OpenAIMessage[] = [];\n\n for (const msg of messages) {\n const role = msg.role === \"model\" ? \"assistant\" : \"user\";\n const parts: any[] = msg.parts ?? [];\n\n if (role === \"user\") {\n // Check for functionResponse parts\n const funcResponses = parts.filter((p: any) => p.functionResponse);\n const textParts = parts.filter((p: any) => p.text !== undefined);\n\n if (textParts.length > 0) {\n result.push({ role: \"user\", content: textParts.map((p: any) => p.text).join(\"\\n\") });\n }\n for (const fr of funcResponses) {\n result.push({\n role: \"tool\",\n content: JSON.stringify(fr.functionResponse.response),\n tool_call_id: `gemini_${fr.functionResponse.name}`,\n });\n }\n continue;\n }\n\n if (role === \"assistant\") {\n const textParts = parts.filter((p: any) => p.text !== undefined);\n const funcCalls = parts.filter((p: any) => p.functionCall);\n\n const content = textParts.length > 0 ? textParts.map((p: any) => p.text).join(\"\\n\") : null;\n const openaiMsg: AssistantMessage = { role: \"assistant\", content };\n\n if (funcCalls.length > 0) {\n openaiMsg.tool_calls = funcCalls.map((p: any): ToolCall => ({\n id: `gemini_${p.functionCall.name}`,\n type: \"function\",\n function: {\n name: p.functionCall.name,\n arguments: JSON.stringify(p.functionCall.args),\n },\n }));\n }\n result.push(openaiMsg);\n continue;\n }\n }\n\n return result;\n}\n\nexport function openAIToGemini(messages: OpenAIMessage[]): any[] {\n const result: any[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") {\n // Gemini system is top-level; if in messages, convert to user\n result.push({ role: \"user\", parts: [{ text: msg.content }] });\n continue;\n }\n\n if (msg.role === \"user\") {\n const text = typeof msg.content === \"string\"\n ? msg.content\n : (msg.content ?? []).filter((p) => p.type === \"text\").map((p) => (p as any).text).join(\"\\n\");\n result.push({ role: \"user\", parts: [{ text }] });\n continue;\n }\n\n if (msg.role === \"assistant\") {\n const parts: any[] = [];\n if (msg.content) parts.push({ text: msg.content });\n if (msg.tool_calls) {\n for (const tc of msg.tool_calls) {\n parts.push({\n functionCall: { name: tc.function.name, args: JSON.parse(tc.function.arguments) },\n });\n }\n }\n result.push({ role: \"model\", parts });\n continue;\n }\n\n if (msg.role === \"tool\") {\n let response: any;\n try { response = JSON.parse(msg.content); } catch { response = { result: msg.content }; }\n result.push({\n role: \"user\",\n parts: [{ functionResponse: { name: msg.tool_call_id?.replace(\"gemini_\", \"\") ?? \"unknown\", response } }],\n });\n continue;\n }\n }\n\n return result;\n}\n\n// ============================================================\n// Universal: any format → OpenAI, and OpenAI → original format\n// ============================================================\n\nexport function toOpenAI(messages: any[]): OpenAIMessage[] {\n const format = detectFormat(messages);\n switch (format) {\n case \"openai\": return messages as OpenAIMessage[];\n case \"anthropic\": return anthropicToOpenAI(messages);\n case \"vercel\": return vercelToOpenAI(messages);\n case \"gemini\": return geminiToOpenAI(messages);\n }\n}\n\nexport function fromOpenAI(messages: OpenAIMessage[], targetFormat: MessageFormat): any[] {\n switch (targetFormat) {\n case \"openai\": return messages;\n case \"anthropic\": return openAIToAnthropic(messages);\n case \"vercel\": return openAIToVercel(messages);\n case \"gemini\": return openAIToGemini(messages);\n }\n}\n","import { HeadroomClient } from \"./client.js\";\nimport type {\n CompressResult,\n CompressOptions,\n} from \"./types.js\";\nimport { detectFormat, toOpenAI, fromOpenAI } from \"./utils/format.js\";\n\n/**\n * Compress an array of messages using the Headroom proxy or cloud.\n *\n * Accepts messages in any format: OpenAI, Anthropic, Vercel AI SDK, or Google Gemini.\n * Detects the format automatically, compresses via the proxy, and returns\n * compressed messages in the same format as the input.\n *\n * @example\n * ```typescript\n * import { compress } from 'headroom-ai';\n *\n * // Works with any message format:\n * const result = await compress(openaiMessages, { model: 'gpt-4o' });\n * const result = await compress(anthropicMessages, { model: 'claude-sonnet-4-5-20250929' });\n * const result = await compress(vercelMessages, { model: 'gpt-4o' });\n * const result = await compress(geminiContents, { model: 'gemini-2.0-flash' });\n *\n * // result.messages is in the same format as input\n * ```\n */\nexport async function compress(\n messages: any[],\n options: CompressOptions = {},\n): Promise<CompressResult> {\n const { client: providedClient, model, ...clientOptions } = options;\n\n // Detect input format\n const inputFormat = detectFormat(messages);\n\n // Convert to OpenAI format (the proxy's lingua franca)\n const openaiMessages = toOpenAI(messages);\n\n // Compress via proxy\n const client = providedClient ?? new HeadroomClient(clientOptions);\n const result = await client.compress(openaiMessages, { model });\n\n // Convert compressed messages back to original format\n const outputMessages = fromOpenAI(result.messages, inputFormat);\n\n return {\n ...result,\n messages: outputMessages,\n };\n}\n"]}
@@ -0,0 +1,526 @@
1
+ // src/types.ts
2
+ var HeadroomError = class extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "HeadroomError";
6
+ }
7
+ };
8
+ var HeadroomConnectionError = class extends HeadroomError {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "HeadroomConnectionError";
12
+ }
13
+ };
14
+ var HeadroomAuthError = class extends HeadroomError {
15
+ constructor(message) {
16
+ super(message);
17
+ this.name = "HeadroomAuthError";
18
+ }
19
+ };
20
+ var HeadroomCompressError = class extends HeadroomError {
21
+ statusCode;
22
+ errorType;
23
+ constructor(statusCode, errorType, message) {
24
+ super(message);
25
+ this.name = "HeadroomCompressError";
26
+ this.statusCode = statusCode;
27
+ this.errorType = errorType;
28
+ }
29
+ };
30
+
31
+ // src/client.ts
32
+ var DEFAULT_BASE_URL = "http://localhost:8787";
33
+ var DEFAULT_TIMEOUT = 3e4;
34
+ var DEFAULT_RETRIES = 1;
35
+ function getEnv(key) {
36
+ if (typeof process !== "undefined" && process.env) {
37
+ return process.env[key];
38
+ }
39
+ return void 0;
40
+ }
41
+ function makeFallbackResult(messages) {
42
+ return {
43
+ messages,
44
+ tokensBefore: 0,
45
+ tokensAfter: 0,
46
+ tokensSaved: 0,
47
+ compressionRatio: 1,
48
+ transformsApplied: [],
49
+ ccrHashes: [],
50
+ compressed: false
51
+ };
52
+ }
53
+ var HeadroomClient = class {
54
+ baseUrl;
55
+ apiKey;
56
+ timeout;
57
+ fallback;
58
+ retries;
59
+ constructor(options = {}) {
60
+ this.baseUrl = (options.baseUrl ?? getEnv("HEADROOM_BASE_URL") ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
61
+ this.apiKey = options.apiKey ?? getEnv("HEADROOM_API_KEY");
62
+ this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
63
+ this.fallback = options.fallback ?? true;
64
+ this.retries = options.retries ?? DEFAULT_RETRIES;
65
+ }
66
+ async compress(messages, options = {}) {
67
+ const model = options.model ?? "gpt-4o";
68
+ let lastError;
69
+ const maxAttempts = 1 + this.retries;
70
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
71
+ try {
72
+ return await this._doCompress(messages, model);
73
+ } catch (error) {
74
+ lastError = error;
75
+ if (error instanceof HeadroomAuthError) throw error;
76
+ if (error instanceof HeadroomCompressError && error.statusCode < 500) {
77
+ throw error;
78
+ }
79
+ }
80
+ }
81
+ if (this.fallback) {
82
+ return makeFallbackResult(messages);
83
+ }
84
+ if (lastError instanceof HeadroomConnectionError) throw lastError;
85
+ if (lastError instanceof HeadroomCompressError) throw lastError;
86
+ throw new HeadroomConnectionError(
87
+ `Failed after ${maxAttempts} attempts: ${lastError}`
88
+ );
89
+ }
90
+ async _doCompress(messages, model) {
91
+ const url = `${this.baseUrl}/v1/compress`;
92
+ const headers = {
93
+ "Content-Type": "application/json"
94
+ };
95
+ if (this.apiKey) {
96
+ headers["Authorization"] = `Bearer ${this.apiKey}`;
97
+ }
98
+ let response;
99
+ try {
100
+ response = await fetch(url, {
101
+ method: "POST",
102
+ headers,
103
+ body: JSON.stringify({ messages, model }),
104
+ signal: AbortSignal.timeout(this.timeout)
105
+ });
106
+ } catch (error) {
107
+ throw new HeadroomConnectionError(
108
+ `Failed to connect to Headroom at ${this.baseUrl}: ${error}`
109
+ );
110
+ }
111
+ if (!response.ok) {
112
+ let errorBody;
113
+ try {
114
+ errorBody = await response.json();
115
+ } catch {
116
+ }
117
+ const errorType = errorBody?.error?.type ?? "unknown";
118
+ const errorMessage = errorBody?.error?.message ?? `HTTP ${response.status}`;
119
+ if (response.status === 401) {
120
+ throw new HeadroomAuthError(errorMessage);
121
+ }
122
+ throw new HeadroomCompressError(response.status, errorType, errorMessage);
123
+ }
124
+ const data = await response.json();
125
+ return {
126
+ messages: data.messages,
127
+ tokensBefore: data.tokens_before,
128
+ tokensAfter: data.tokens_after,
129
+ tokensSaved: data.tokens_saved,
130
+ compressionRatio: data.compression_ratio,
131
+ transformsApplied: data.transforms_applied,
132
+ ccrHashes: data.ccr_hashes,
133
+ compressed: true
134
+ };
135
+ }
136
+ };
137
+
138
+ // src/utils/format.ts
139
+ function detectFormat(messages) {
140
+ for (const msg of messages) {
141
+ if ("parts" in msg && !("content" in msg)) return "gemini";
142
+ if (msg.role === "model") return "gemini";
143
+ if (msg.tool_calls && msg.role === "assistant") return "openai";
144
+ if (msg.role === "tool" && "tool_call_id" in msg && typeof msg.content === "string") return "openai";
145
+ if (Array.isArray(msg.content)) {
146
+ for (const part of msg.content) {
147
+ if (part.type === "tool-call" || part.type === "tool-result") return "vercel";
148
+ if (part.type === "tool_use" || part.type === "tool_result") return "anthropic";
149
+ if (part.type === "image" && part.source?.type) return "anthropic";
150
+ }
151
+ }
152
+ }
153
+ return "openai";
154
+ }
155
+ function anthropicToOpenAI(messages) {
156
+ const result = [];
157
+ for (const msg of messages) {
158
+ if (msg.role === "user") {
159
+ if (typeof msg.content === "string") {
160
+ result.push({ role: "user", content: msg.content });
161
+ continue;
162
+ }
163
+ if (Array.isArray(msg.content)) {
164
+ const textBlocks = msg.content.filter((b) => b.type === "text");
165
+ const toolResults = msg.content.filter((b) => b.type === "tool_result");
166
+ if (textBlocks.length > 0) {
167
+ result.push({
168
+ role: "user",
169
+ content: textBlocks.map((b) => b.text).join("\n")
170
+ });
171
+ }
172
+ for (const tr of toolResults) {
173
+ const content = typeof tr.content === "string" ? tr.content : Array.isArray(tr.content) ? tr.content.map((b) => b.text ?? JSON.stringify(b)).join("\n") : JSON.stringify(tr.content);
174
+ result.push({
175
+ role: "tool",
176
+ content,
177
+ tool_call_id: tr.tool_use_id
178
+ });
179
+ }
180
+ }
181
+ continue;
182
+ }
183
+ if (msg.role === "assistant") {
184
+ if (typeof msg.content === "string") {
185
+ result.push({ role: "assistant", content: msg.content });
186
+ continue;
187
+ }
188
+ if (Array.isArray(msg.content)) {
189
+ const textBlocks = msg.content.filter((b) => b.type === "text");
190
+ const toolUseBlocks = msg.content.filter((b) => b.type === "tool_use");
191
+ const content = textBlocks.length > 0 ? textBlocks.map((b) => b.text).join("\n") : null;
192
+ const openaiMsg = { role: "assistant", content };
193
+ if (toolUseBlocks.length > 0) {
194
+ openaiMsg.tool_calls = toolUseBlocks.map((b) => ({
195
+ id: b.id,
196
+ type: "function",
197
+ function: {
198
+ name: b.name,
199
+ arguments: typeof b.input === "string" ? b.input : JSON.stringify(b.input)
200
+ }
201
+ }));
202
+ }
203
+ result.push(openaiMsg);
204
+ }
205
+ continue;
206
+ }
207
+ }
208
+ return result;
209
+ }
210
+ function openAIToAnthropic(messages) {
211
+ const result = [];
212
+ for (const msg of messages) {
213
+ if (msg.role === "system") {
214
+ result.push({ role: "user", content: msg.content });
215
+ continue;
216
+ }
217
+ if (msg.role === "user") {
218
+ if (typeof msg.content === "string") {
219
+ result.push({ role: "user", content: msg.content });
220
+ } else if (Array.isArray(msg.content)) {
221
+ result.push({
222
+ role: "user",
223
+ content: msg.content.map(
224
+ (p) => p.type === "text" ? { type: "text", text: p.text } : { type: "text", text: "" }
225
+ )
226
+ });
227
+ }
228
+ continue;
229
+ }
230
+ if (msg.role === "assistant") {
231
+ const blocks = [];
232
+ if (msg.content) blocks.push({ type: "text", text: msg.content });
233
+ if (msg.tool_calls) {
234
+ for (const tc of msg.tool_calls) {
235
+ blocks.push({
236
+ type: "tool_use",
237
+ id: tc.id,
238
+ name: tc.function.name,
239
+ input: JSON.parse(tc.function.arguments)
240
+ });
241
+ }
242
+ }
243
+ result.push({
244
+ role: "assistant",
245
+ content: blocks.length === 1 && blocks[0].type === "text" ? blocks[0].text : blocks
246
+ });
247
+ continue;
248
+ }
249
+ if (msg.role === "tool") {
250
+ result.push({
251
+ role: "user",
252
+ content: [
253
+ { type: "tool_result", tool_use_id: msg.tool_call_id, content: msg.content }
254
+ ]
255
+ });
256
+ continue;
257
+ }
258
+ }
259
+ return result;
260
+ }
261
+ function vercelToOpenAI(messages) {
262
+ const result = [];
263
+ for (const msg of messages) {
264
+ if (msg.role === "system") {
265
+ result.push({ role: "system", content: typeof msg.content === "string" ? msg.content : String(msg.content) });
266
+ continue;
267
+ }
268
+ if (msg.role === "user") {
269
+ if (typeof msg.content === "string") {
270
+ result.push({ role: "user", content: msg.content });
271
+ continue;
272
+ }
273
+ const parts = Array.isArray(msg.content) ? msg.content : [];
274
+ const textParts = parts.filter((p) => p.type === "text");
275
+ const imageParts = parts.filter((p) => p.type === "image");
276
+ if (imageParts.length === 0 && textParts.length > 0) {
277
+ result.push({ role: "user", content: textParts.map((p) => p.text).join("") });
278
+ } else {
279
+ const openaiParts = parts.filter((p) => p.type === "text" || p.type === "image").map((p) => {
280
+ if (p.type === "text") return { type: "text", text: p.text };
281
+ if (p.type === "image") {
282
+ const url = p.image instanceof URL ? p.image.toString() : String(p.image);
283
+ return { type: "image_url", image_url: { url } };
284
+ }
285
+ return { type: "text", text: "" };
286
+ });
287
+ result.push({ role: "user", content: openaiParts });
288
+ }
289
+ continue;
290
+ }
291
+ if (msg.role === "assistant") {
292
+ if (typeof msg.content === "string") {
293
+ result.push({ role: "assistant", content: msg.content });
294
+ continue;
295
+ }
296
+ const parts = Array.isArray(msg.content) ? msg.content : [];
297
+ const textParts = parts.filter((p) => p.type === "text");
298
+ const toolCallParts = parts.filter((p) => p.type === "tool-call");
299
+ const content = textParts.length > 0 ? textParts.map((p) => p.text).join("") : null;
300
+ const openaiMsg = { role: "assistant", content };
301
+ if (toolCallParts.length > 0) {
302
+ openaiMsg.tool_calls = toolCallParts.map((p) => ({
303
+ id: p.toolCallId,
304
+ type: "function",
305
+ // AI SDK v6 uses `input`, earlier versions used `args`
306
+ function: { name: p.toolName, arguments: JSON.stringify(p.input ?? p.args) }
307
+ }));
308
+ }
309
+ result.push(openaiMsg);
310
+ continue;
311
+ }
312
+ if (msg.role === "tool") {
313
+ const parts = Array.isArray(msg.content) ? msg.content : [];
314
+ for (const part of parts) {
315
+ if (part.type === "tool-result") {
316
+ let contentStr;
317
+ if (part.output !== void 0) {
318
+ const val = part.output?.value ?? part.output;
319
+ contentStr = typeof val === "string" ? val : JSON.stringify(val);
320
+ } else if (part.result !== void 0) {
321
+ contentStr = typeof part.result === "string" ? part.result : JSON.stringify(part.result);
322
+ } else {
323
+ contentStr = "";
324
+ }
325
+ result.push({
326
+ role: "tool",
327
+ content: contentStr,
328
+ tool_call_id: part.toolCallId
329
+ });
330
+ }
331
+ }
332
+ continue;
333
+ }
334
+ }
335
+ return result;
336
+ }
337
+ function openAIToVercel(messages) {
338
+ const result = [];
339
+ for (const msg of messages) {
340
+ if (msg.role === "system") {
341
+ result.push({ role: "system", content: msg.content });
342
+ continue;
343
+ }
344
+ if (msg.role === "user") {
345
+ if (typeof msg.content === "string") {
346
+ result.push({ role: "user", content: [{ type: "text", text: msg.content }] });
347
+ } else if (Array.isArray(msg.content)) {
348
+ const parts = msg.content.map((p) => {
349
+ if (p.type === "text") return { type: "text", text: p.text };
350
+ if (p.type === "image_url") return { type: "image", image: new URL(p.image_url.url) };
351
+ return { type: "text", text: "" };
352
+ });
353
+ result.push({ role: "user", content: parts });
354
+ }
355
+ continue;
356
+ }
357
+ if (msg.role === "assistant") {
358
+ const parts = [];
359
+ if (msg.content) parts.push({ type: "text", text: msg.content });
360
+ if (msg.tool_calls) {
361
+ for (const tc of msg.tool_calls) {
362
+ let input;
363
+ try {
364
+ input = JSON.parse(tc.function.arguments);
365
+ } catch {
366
+ input = tc.function.arguments ?? {};
367
+ }
368
+ parts.push({
369
+ type: "tool-call",
370
+ toolCallId: tc.id,
371
+ toolName: tc.function.name,
372
+ input
373
+ // AI SDK v6 uses `input`, not `args`
374
+ });
375
+ }
376
+ }
377
+ result.push({ role: "assistant", content: parts });
378
+ continue;
379
+ }
380
+ if (msg.role === "tool") {
381
+ let parsed;
382
+ try {
383
+ parsed = JSON.parse(msg.content);
384
+ } catch {
385
+ parsed = msg.content;
386
+ }
387
+ const output = typeof parsed === "string" ? { type: "text", value: parsed } : { type: "json", value: parsed };
388
+ result.push({
389
+ role: "tool",
390
+ content: [{
391
+ type: "tool-result",
392
+ toolCallId: msg.tool_call_id,
393
+ toolName: "unknown",
394
+ output
395
+ }]
396
+ });
397
+ continue;
398
+ }
399
+ }
400
+ return result;
401
+ }
402
+ function geminiToOpenAI(messages) {
403
+ const result = [];
404
+ for (const msg of messages) {
405
+ const role = msg.role === "model" ? "assistant" : "user";
406
+ const parts = msg.parts ?? [];
407
+ if (role === "user") {
408
+ const funcResponses = parts.filter((p) => p.functionResponse);
409
+ const textParts = parts.filter((p) => p.text !== void 0);
410
+ if (textParts.length > 0) {
411
+ result.push({ role: "user", content: textParts.map((p) => p.text).join("\n") });
412
+ }
413
+ for (const fr of funcResponses) {
414
+ result.push({
415
+ role: "tool",
416
+ content: JSON.stringify(fr.functionResponse.response),
417
+ tool_call_id: `gemini_${fr.functionResponse.name}`
418
+ });
419
+ }
420
+ continue;
421
+ }
422
+ if (role === "assistant") {
423
+ const textParts = parts.filter((p) => p.text !== void 0);
424
+ const funcCalls = parts.filter((p) => p.functionCall);
425
+ const content = textParts.length > 0 ? textParts.map((p) => p.text).join("\n") : null;
426
+ const openaiMsg = { role: "assistant", content };
427
+ if (funcCalls.length > 0) {
428
+ openaiMsg.tool_calls = funcCalls.map((p) => ({
429
+ id: `gemini_${p.functionCall.name}`,
430
+ type: "function",
431
+ function: {
432
+ name: p.functionCall.name,
433
+ arguments: JSON.stringify(p.functionCall.args)
434
+ }
435
+ }));
436
+ }
437
+ result.push(openaiMsg);
438
+ continue;
439
+ }
440
+ }
441
+ return result;
442
+ }
443
+ function openAIToGemini(messages) {
444
+ const result = [];
445
+ for (const msg of messages) {
446
+ if (msg.role === "system") {
447
+ result.push({ role: "user", parts: [{ text: msg.content }] });
448
+ continue;
449
+ }
450
+ if (msg.role === "user") {
451
+ const text = typeof msg.content === "string" ? msg.content : (msg.content ?? []).filter((p) => p.type === "text").map((p) => p.text).join("\n");
452
+ result.push({ role: "user", parts: [{ text }] });
453
+ continue;
454
+ }
455
+ if (msg.role === "assistant") {
456
+ const parts = [];
457
+ if (msg.content) parts.push({ text: msg.content });
458
+ if (msg.tool_calls) {
459
+ for (const tc of msg.tool_calls) {
460
+ parts.push({
461
+ functionCall: { name: tc.function.name, args: JSON.parse(tc.function.arguments) }
462
+ });
463
+ }
464
+ }
465
+ result.push({ role: "model", parts });
466
+ continue;
467
+ }
468
+ if (msg.role === "tool") {
469
+ let response;
470
+ try {
471
+ response = JSON.parse(msg.content);
472
+ } catch {
473
+ response = { result: msg.content };
474
+ }
475
+ result.push({
476
+ role: "user",
477
+ parts: [{ functionResponse: { name: msg.tool_call_id?.replace("gemini_", "") ?? "unknown", response } }]
478
+ });
479
+ continue;
480
+ }
481
+ }
482
+ return result;
483
+ }
484
+ function toOpenAI(messages) {
485
+ const format = detectFormat(messages);
486
+ switch (format) {
487
+ case "openai":
488
+ return messages;
489
+ case "anthropic":
490
+ return anthropicToOpenAI(messages);
491
+ case "vercel":
492
+ return vercelToOpenAI(messages);
493
+ case "gemini":
494
+ return geminiToOpenAI(messages);
495
+ }
496
+ }
497
+ function fromOpenAI(messages, targetFormat) {
498
+ switch (targetFormat) {
499
+ case "openai":
500
+ return messages;
501
+ case "anthropic":
502
+ return openAIToAnthropic(messages);
503
+ case "vercel":
504
+ return openAIToVercel(messages);
505
+ case "gemini":
506
+ return openAIToGemini(messages);
507
+ }
508
+ }
509
+
510
+ // src/compress.ts
511
+ async function compress(messages, options = {}) {
512
+ const { client: providedClient, model, ...clientOptions } = options;
513
+ const inputFormat = detectFormat(messages);
514
+ const openaiMessages = toOpenAI(messages);
515
+ const client = providedClient ?? new HeadroomClient(clientOptions);
516
+ const result = await client.compress(openaiMessages, { model });
517
+ const outputMessages = fromOpenAI(result.messages, inputFormat);
518
+ return {
519
+ ...result,
520
+ messages: outputMessages
521
+ };
522
+ }
523
+
524
+ export { HeadroomAuthError, HeadroomClient, HeadroomCompressError, HeadroomConnectionError, HeadroomError, compress, detectFormat, fromOpenAI, openAIToVercel, toOpenAI, vercelToOpenAI };
525
+ //# sourceMappingURL=chunk-YTTW7S2Q.js.map
526
+ //# sourceMappingURL=chunk-YTTW7S2Q.js.map