headroom-ai 0.1.0 → 0.22.4

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.
Files changed (44) hide show
  1. package/README.md +300 -14
  2. package/dist/adapters/anthropic.cjs +6 -2
  3. package/dist/adapters/anthropic.cjs.map +1 -1
  4. package/dist/adapters/anthropic.d.cts +1 -1
  5. package/dist/adapters/anthropic.d.ts +1 -1
  6. package/dist/adapters/anthropic.js +6 -2
  7. package/dist/adapters/anthropic.js.map +1 -1
  8. package/dist/adapters/gemini.cjs +41 -0
  9. package/dist/adapters/gemini.cjs.map +1 -0
  10. package/dist/adapters/gemini.d.cts +31 -0
  11. package/dist/adapters/gemini.d.ts +31 -0
  12. package/dist/adapters/gemini.js +39 -0
  13. package/dist/adapters/gemini.js.map +1 -0
  14. package/dist/adapters/openai.cjs +6 -2
  15. package/dist/adapters/openai.cjs.map +1 -1
  16. package/dist/adapters/openai.d.cts +1 -1
  17. package/dist/adapters/openai.d.ts +1 -1
  18. package/dist/adapters/openai.js +6 -2
  19. package/dist/adapters/openai.js.map +1 -1
  20. package/dist/adapters/vercel-ai.cjs +33 -8
  21. package/dist/adapters/vercel-ai.cjs.map +1 -1
  22. package/dist/adapters/vercel-ai.d.cts +30 -2
  23. package/dist/adapters/vercel-ai.d.ts +30 -2
  24. package/dist/adapters/vercel-ai.js +28 -5
  25. package/dist/adapters/vercel-ai.js.map +1 -1
  26. package/dist/chunk-7AJIWIPP.js +1108 -0
  27. package/dist/chunk-7AJIWIPP.js.map +1 -0
  28. package/dist/chunk-R6FB52AD.cjs +1139 -0
  29. package/dist/chunk-R6FB52AD.cjs.map +1 -0
  30. package/dist/index.cjs +430 -10
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +797 -18
  33. package/dist/index.d.ts +797 -18
  34. package/dist/index.js +326 -1
  35. package/dist/index.js.map +1 -1
  36. package/dist/types-BTrX7__W.d.cts +149 -0
  37. package/dist/types-BTrX7__W.d.ts +149 -0
  38. package/package.json +12 -2
  39. package/dist/chunk-3N25JEWK.cjs +0 -538
  40. package/dist/chunk-3N25JEWK.cjs.map +0 -1
  41. package/dist/chunk-YTTW7S2Q.js +0 -526
  42. package/dist/chunk-YTTW7S2Q.js.map +0 -1
  43. package/dist/types-DQtcLXq3.d.cts +0 -87
  44. package/dist/types-DQtcLXq3.d.ts +0 -87
@@ -0,0 +1,39 @@
1
+ import { compress } from '../chunk-7AJIWIPP.js';
2
+
3
+ // src/adapters/gemini.ts
4
+ function withHeadroom(model, options = {}) {
5
+ const originalGenerate = model.generateContent.bind(model);
6
+ const originalStream = model.generateContentStream?.bind(model);
7
+ const compressedGenerate = async (params) => {
8
+ const contents = params.contents ?? params;
9
+ const modelName = options.model ?? "gemini-2.0-flash";
10
+ const result = await compress(
11
+ Array.isArray(contents) ? contents : [contents],
12
+ { stack: "adapter_ts_gemini", ...options, model: modelName }
13
+ );
14
+ const newParams = Array.isArray(params) ? result.messages : { ...params, contents: result.messages };
15
+ return originalGenerate(newParams);
16
+ };
17
+ const compressedStream = originalStream ? async (params) => {
18
+ const contents = params.contents ?? params;
19
+ const modelName = options.model ?? "gemini-2.0-flash";
20
+ const result = await compress(
21
+ Array.isArray(contents) ? contents : [contents],
22
+ { stack: "adapter_ts_gemini", ...options, model: modelName }
23
+ );
24
+ const newParams = Array.isArray(params) ? result.messages : { ...params, contents: result.messages };
25
+ return originalStream(newParams);
26
+ } : void 0;
27
+ return new Proxy(model, {
28
+ get(target, prop) {
29
+ if (prop === "generateContent") return compressedGenerate;
30
+ if (prop === "generateContentStream" && compressedStream)
31
+ return compressedStream;
32
+ return target[prop];
33
+ }
34
+ });
35
+ }
36
+
37
+ export { withHeadroom };
38
+ //# sourceMappingURL=gemini.js.map
39
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":";;;AAgCO,SAAS,YAAA,CACd,KAAA,EACA,OAAA,GAA2B,EAAC,EACzB;AACH,EAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,eAAA,CAAgB,IAAA,CAAK,KAAK,CAAA;AACzD,EAAA,MAAM,cAAA,GAAiB,KAAA,CAAM,qBAAA,EAAuB,IAAA,CAAK,KAAK,CAAA;AAE9D,EAAA,MAAM,kBAAA,GAAqB,OAAO,MAAA,KAAgB;AAChD,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,MAAA;AACpC,IAAA,MAAM,SAAA,GAAY,QAAQ,KAAA,IAAS,kBAAA;AAGnC,IAAA,MAAM,SAAS,MAAM,QAAA;AAAA,MACnB,MAAM,OAAA,CAAQ,QAAQ,CAAA,GAAI,QAAA,GAAW,CAAC,QAAQ,CAAA;AAAA,MAC9C,EAAE,KAAA,EAAO,mBAAA,EAAqB,GAAG,OAAA,EAAS,OAAO,SAAA;AAAU,KAC7D;AAEA,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAClC,MAAA,CAAO,QAAA,GACP,EAAE,GAAG,MAAA,EAAQ,QAAA,EAAU,MAAA,CAAO,QAAA,EAAS;AAE3C,IAAA,OAAO,iBAAiB,SAAS,CAAA;AAAA,EACnC,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,cAAA,GACrB,OAAO,MAAA,KAAgB;AACrB,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,IAAY,MAAA;AACpC,IAAA,MAAM,SAAA,GAAY,QAAQ,KAAA,IAAS,kBAAA;AAEnC,IAAA,MAAM,SAAS,MAAM,QAAA;AAAA,MACnB,MAAM,OAAA,CAAQ,QAAQ,CAAA,GAAI,QAAA,GAAW,CAAC,QAAQ,CAAA;AAAA,MAC9C,EAAE,KAAA,EAAO,mBAAA,EAAqB,GAAG,OAAA,EAAS,OAAO,SAAA;AAAU,KAC7D;AAEA,IAAA,MAAM,SAAA,GAAY,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,GAClC,MAAA,CAAO,QAAA,GACP,EAAE,GAAG,MAAA,EAAQ,QAAA,EAAU,MAAA,CAAO,QAAA,EAAS;AAE3C,IAAA,OAAO,eAAe,SAAS,CAAA;AAAA,EACjC,CAAA,GACA,MAAA;AAEJ,EAAA,OAAO,IAAI,MAAM,KAAA,EAAO;AAAA,IACtB,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,mBAAmB,OAAO,kBAAA;AACvC,MAAA,IAAI,SAAS,uBAAA,IAA2B,gBAAA;AACtC,QAAA,OAAO,gBAAA;AACT,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AACH","file":"gemini.js","sourcesContent":["/**\n * Gemini adapter — wraps Google Generative AI model with auto-compression.\n * Matches the pattern of openai.ts and anthropic.ts adapters.\n */\n\nimport { compress } from \"../compress.js\";\nimport type { CompressOptions } from \"../types.js\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface GeminiModelLike {\n generateContent: (params: any) => any;\n generateContentStream?: (params: any) => any;\n [key: string]: any;\n}\n\n/**\n * Wrap a Google Generative AI model to auto-compress before each request.\n *\n * Intercepts `model.generateContent()` and `model.generateContentStream()`.\n *\n * @example\n * ```typescript\n * import { withHeadroom } from 'headroom-ai/gemini';\n * import { GoogleGenerativeAI } from '@google/generative-ai';\n *\n * const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY!);\n * const model = withHeadroom(genAI.getGenerativeModel({ model: 'gemini-2.0-flash' }));\n *\n * const result = await model.generateContent({ contents: longConversation });\n * ```\n */\nexport function withHeadroom<T extends GeminiModelLike>(\n model: T,\n options: CompressOptions = {},\n): T {\n const originalGenerate = model.generateContent.bind(model);\n const originalStream = model.generateContentStream?.bind(model);\n\n const compressedGenerate = async (params: any) => {\n const contents = params.contents ?? params;\n const modelName = options.model ?? \"gemini-2.0-flash\";\n\n // compress() auto-detects Gemini format\n const result = await compress(\n Array.isArray(contents) ? contents : [contents],\n { stack: \"adapter_ts_gemini\", ...options, model: modelName },\n );\n\n const newParams = Array.isArray(params)\n ? result.messages\n : { ...params, contents: result.messages };\n\n return originalGenerate(newParams);\n };\n\n const compressedStream = originalStream\n ? async (params: any) => {\n const contents = params.contents ?? params;\n const modelName = options.model ?? \"gemini-2.0-flash\";\n\n const result = await compress(\n Array.isArray(contents) ? contents : [contents],\n { stack: \"adapter_ts_gemini\", ...options, model: modelName },\n );\n\n const newParams = Array.isArray(params)\n ? result.messages\n : { ...params, contents: result.messages };\n\n return originalStream(newParams);\n }\n : undefined;\n\n return new Proxy(model, {\n get(target, prop) {\n if (prop === \"generateContent\") return compressedGenerate;\n if (prop === \"generateContentStream\" && compressedStream)\n return compressedStream;\n return (target as any)[prop];\n },\n }) as T;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk3N25JEWK_cjs = require('../chunk-3N25JEWK.cjs');
3
+ var chunkR6FB52AD_cjs = require('../chunk-R6FB52AD.cjs');
4
4
 
5
5
  // src/adapters/openai.ts
6
6
  function withHeadroom(client, options = {}) {
@@ -10,7 +10,11 @@ function withHeadroom(client, options = {}) {
10
10
  const compressedCreate = async (params) => {
11
11
  const messages = params.messages;
12
12
  const model = options.model ?? params.model ?? "gpt-4o";
13
- const result = await chunk3N25JEWK_cjs.compress(messages, { ...options, model });
13
+ const result = await chunkR6FB52AD_cjs.compress(messages, {
14
+ stack: "adapter_ts_openai",
15
+ ...options,
16
+ model
17
+ });
14
18
  return originalCreate({
15
19
  ...params,
16
20
  messages: result.messages
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/openai.ts"],"names":["compress"],"mappings":";;;;;AAgCO,SAAS,YAAA,CACd,MAAA,EACA,OAAA,GAA2B,EAAC,EACzB;AACH,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,IAAA;AAAA,IACpD,OAAO,IAAA,CAAK;AAAA,GACd;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAO,MAAA,KAAgB;AAC9C,IAAA,MAAM,WAA4B,MAAA,CAAO,QAAA;AACzC,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,KAAA,IAAS,QAAA;AAE/C,IAAA,MAAM,MAAA,GAAS,MAAMA,0BAAA,CAAS,QAAA,EAAU,EAAE,GAAG,OAAA,EAAS,OAAO,CAAA;AAE7D,IAAA,OAAO,cAAA,CAAe;AAAA,MACpB,GAAG,MAAA;AAAA,MACH,UAAU,MAAA,CAAO;AAAA,KAClB,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,WAAA,EAAa;AAAA,IAC1D,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,UAAU,OAAO,gBAAA;AAC9B,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,MAAM,SAAA,GAAY,IAAI,KAAA,CAAM,MAAA,CAAO,IAAA,EAAM;AAAA,IACvC,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,eAAe,OAAO,gBAAA;AACnC,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,OAAO,IAAI,MAAM,MAAA,EAAQ;AAAA,IACvB,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,SAAA;AAC5B,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AACH","file":"openai.cjs","sourcesContent":["import { compress } from \"../compress.js\";\nimport type { CompressOptions, OpenAIMessage } from \"../types.js\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface OpenAILike {\n chat: {\n completions: {\n create: (params: any) => any;\n };\n };\n [key: string]: any;\n}\n\n/**\n * Wrap an OpenAI client to auto-compress messages before each request.\n *\n * Intercepts `client.chat.completions.create()` only. All other methods\n * (embeddings, images, audio, etc.) pass through unchanged.\n *\n * @example\n * ```typescript\n * import { withHeadroom } from 'headroom-ai/openai';\n * import OpenAI from 'openai';\n *\n * const client = withHeadroom(new OpenAI());\n * const response = await client.chat.completions.create({\n * model: 'gpt-4o',\n * messages: longConversation,\n * });\n * ```\n */\nexport function withHeadroom<T extends OpenAILike>(\n client: T,\n options: CompressOptions = {},\n): T {\n const originalCreate = client.chat.completions.create.bind(\n client.chat.completions,\n );\n\n const compressedCreate = async (params: any) => {\n const messages: OpenAIMessage[] = params.messages;\n const model = options.model ?? params.model ?? \"gpt-4o\";\n\n const result = await compress(messages, { ...options, model });\n\n return originalCreate({\n ...params,\n messages: result.messages,\n });\n };\n\n const completionsProxy = new Proxy(client.chat.completions, {\n get(target, prop) {\n if (prop === \"create\") return compressedCreate;\n return (target as any)[prop];\n },\n });\n\n const chatProxy = new Proxy(client.chat, {\n get(target, prop) {\n if (prop === \"completions\") return completionsProxy;\n return (target as any)[prop];\n },\n });\n\n return new Proxy(client, {\n get(target, prop) {\n if (prop === \"chat\") return chatProxy;\n return (target as any)[prop];\n },\n }) as T;\n}\n"]}
1
+ {"version":3,"sources":["../../src/adapters/openai.ts"],"names":["compress"],"mappings":";;;;;AAgCO,SAAS,YAAA,CACd,MAAA,EACA,OAAA,GAA2B,EAAC,EACzB;AACH,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,IAAA;AAAA,IACpD,OAAO,IAAA,CAAK;AAAA,GACd;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAO,MAAA,KAAgB;AAC9C,IAAA,MAAM,WAA4B,MAAA,CAAO,QAAA;AACzC,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,KAAA,IAAS,QAAA;AAE/C,IAAA,MAAM,MAAA,GAAS,MAAMA,0BAAA,CAAS,QAAA,EAAU;AAAA,MACtC,KAAA,EAAO,mBAAA;AAAA,MACP,GAAG,OAAA;AAAA,MACH;AAAA,KACD,CAAA;AAED,IAAA,OAAO,cAAA,CAAe;AAAA,MACpB,GAAG,MAAA;AAAA,MACH,UAAU,MAAA,CAAO;AAAA,KAClB,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,WAAA,EAAa;AAAA,IAC1D,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,UAAU,OAAO,gBAAA;AAC9B,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,MAAM,SAAA,GAAY,IAAI,KAAA,CAAM,MAAA,CAAO,IAAA,EAAM;AAAA,IACvC,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,eAAe,OAAO,gBAAA;AACnC,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,OAAO,IAAI,MAAM,MAAA,EAAQ;AAAA,IACvB,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,SAAA;AAC5B,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AACH","file":"openai.cjs","sourcesContent":["import { compress } from \"../compress.js\";\nimport type { CompressOptions, OpenAIMessage } from \"../types.js\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface OpenAILike {\n chat: {\n completions: {\n create: (params: any) => any;\n };\n };\n [key: string]: any;\n}\n\n/**\n * Wrap an OpenAI client to auto-compress messages before each request.\n *\n * Intercepts `client.chat.completions.create()` only. All other methods\n * (embeddings, images, audio, etc.) pass through unchanged.\n *\n * @example\n * ```typescript\n * import { withHeadroom } from 'headroom-ai/openai';\n * import OpenAI from 'openai';\n *\n * const client = withHeadroom(new OpenAI());\n * const response = await client.chat.completions.create({\n * model: 'gpt-4o',\n * messages: longConversation,\n * });\n * ```\n */\nexport function withHeadroom<T extends OpenAILike>(\n client: T,\n options: CompressOptions = {},\n): T {\n const originalCreate = client.chat.completions.create.bind(\n client.chat.completions,\n );\n\n const compressedCreate = async (params: any) => {\n const messages: OpenAIMessage[] = params.messages;\n const model = options.model ?? params.model ?? \"gpt-4o\";\n\n const result = await compress(messages, {\n stack: \"adapter_ts_openai\",\n ...options,\n model,\n });\n\n return originalCreate({\n ...params,\n messages: result.messages,\n });\n };\n\n const completionsProxy = new Proxy(client.chat.completions, {\n get(target, prop) {\n if (prop === \"create\") return compressedCreate;\n return (target as any)[prop];\n },\n });\n\n const chatProxy = new Proxy(client.chat, {\n get(target, prop) {\n if (prop === \"completions\") return completionsProxy;\n return (target as any)[prop];\n },\n });\n\n return new Proxy(client, {\n get(target, prop) {\n if (prop === \"chat\") return chatProxy;\n return (target as any)[prop];\n },\n }) as T;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { C as CompressOptions } from '../types-DQtcLXq3.cjs';
1
+ import { C as CompressOptions } from '../types-BTrX7__W.cjs';
2
2
 
3
3
  interface OpenAILike {
4
4
  chat: {
@@ -1,4 +1,4 @@
1
- import { C as CompressOptions } from '../types-DQtcLXq3.js';
1
+ import { C as CompressOptions } from '../types-BTrX7__W.js';
2
2
 
3
3
  interface OpenAILike {
4
4
  chat: {
@@ -1,4 +1,4 @@
1
- import { compress } from '../chunk-YTTW7S2Q.js';
1
+ import { compress } from '../chunk-7AJIWIPP.js';
2
2
 
3
3
  // src/adapters/openai.ts
4
4
  function withHeadroom(client, options = {}) {
@@ -8,7 +8,11 @@ function withHeadroom(client, options = {}) {
8
8
  const compressedCreate = async (params) => {
9
9
  const messages = params.messages;
10
10
  const model = options.model ?? params.model ?? "gpt-4o";
11
- const result = await compress(messages, { ...options, model });
11
+ const result = await compress(messages, {
12
+ stack: "adapter_ts_openai",
13
+ ...options,
14
+ model
15
+ });
12
16
  return originalCreate({
13
17
  ...params,
14
18
  messages: result.messages
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/openai.ts"],"names":[],"mappings":";;;AAgCO,SAAS,YAAA,CACd,MAAA,EACA,OAAA,GAA2B,EAAC,EACzB;AACH,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,IAAA;AAAA,IACpD,OAAO,IAAA,CAAK;AAAA,GACd;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAO,MAAA,KAAgB;AAC9C,IAAA,MAAM,WAA4B,MAAA,CAAO,QAAA;AACzC,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,KAAA,IAAS,QAAA;AAE/C,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,QAAA,EAAU,EAAE,GAAG,OAAA,EAAS,OAAO,CAAA;AAE7D,IAAA,OAAO,cAAA,CAAe;AAAA,MACpB,GAAG,MAAA;AAAA,MACH,UAAU,MAAA,CAAO;AAAA,KAClB,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,WAAA,EAAa;AAAA,IAC1D,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,UAAU,OAAO,gBAAA;AAC9B,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,MAAM,SAAA,GAAY,IAAI,KAAA,CAAM,MAAA,CAAO,IAAA,EAAM;AAAA,IACvC,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,eAAe,OAAO,gBAAA;AACnC,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,OAAO,IAAI,MAAM,MAAA,EAAQ;AAAA,IACvB,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,SAAA;AAC5B,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AACH","file":"openai.js","sourcesContent":["import { compress } from \"../compress.js\";\nimport type { CompressOptions, OpenAIMessage } from \"../types.js\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface OpenAILike {\n chat: {\n completions: {\n create: (params: any) => any;\n };\n };\n [key: string]: any;\n}\n\n/**\n * Wrap an OpenAI client to auto-compress messages before each request.\n *\n * Intercepts `client.chat.completions.create()` only. All other methods\n * (embeddings, images, audio, etc.) pass through unchanged.\n *\n * @example\n * ```typescript\n * import { withHeadroom } from 'headroom-ai/openai';\n * import OpenAI from 'openai';\n *\n * const client = withHeadroom(new OpenAI());\n * const response = await client.chat.completions.create({\n * model: 'gpt-4o',\n * messages: longConversation,\n * });\n * ```\n */\nexport function withHeadroom<T extends OpenAILike>(\n client: T,\n options: CompressOptions = {},\n): T {\n const originalCreate = client.chat.completions.create.bind(\n client.chat.completions,\n );\n\n const compressedCreate = async (params: any) => {\n const messages: OpenAIMessage[] = params.messages;\n const model = options.model ?? params.model ?? \"gpt-4o\";\n\n const result = await compress(messages, { ...options, model });\n\n return originalCreate({\n ...params,\n messages: result.messages,\n });\n };\n\n const completionsProxy = new Proxy(client.chat.completions, {\n get(target, prop) {\n if (prop === \"create\") return compressedCreate;\n return (target as any)[prop];\n },\n });\n\n const chatProxy = new Proxy(client.chat, {\n get(target, prop) {\n if (prop === \"completions\") return completionsProxy;\n return (target as any)[prop];\n },\n });\n\n return new Proxy(client, {\n get(target, prop) {\n if (prop === \"chat\") return chatProxy;\n return (target as any)[prop];\n },\n }) as T;\n}\n"]}
1
+ {"version":3,"sources":["../../src/adapters/openai.ts"],"names":[],"mappings":";;;AAgCO,SAAS,YAAA,CACd,MAAA,EACA,OAAA,GAA2B,EAAC,EACzB;AACH,EAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,IAAA,CAAK,WAAA,CAAY,MAAA,CAAO,IAAA;AAAA,IACpD,OAAO,IAAA,CAAK;AAAA,GACd;AAEA,EAAA,MAAM,gBAAA,GAAmB,OAAO,MAAA,KAAgB;AAC9C,IAAA,MAAM,WAA4B,MAAA,CAAO,QAAA;AACzC,IAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,KAAA,IAAS,QAAA;AAE/C,IAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,QAAA,EAAU;AAAA,MACtC,KAAA,EAAO,mBAAA;AAAA,MACP,GAAG,OAAA;AAAA,MACH;AAAA,KACD,CAAA;AAED,IAAA,OAAO,cAAA,CAAe;AAAA,MACpB,GAAG,MAAA;AAAA,MACH,UAAU,MAAA,CAAO;AAAA,KAClB,CAAA;AAAA,EACH,CAAA;AAEA,EAAA,MAAM,gBAAA,GAAmB,IAAI,KAAA,CAAM,MAAA,CAAO,KAAK,WAAA,EAAa;AAAA,IAC1D,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,UAAU,OAAO,gBAAA;AAC9B,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,MAAM,SAAA,GAAY,IAAI,KAAA,CAAM,MAAA,CAAO,IAAA,EAAM;AAAA,IACvC,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,eAAe,OAAO,gBAAA;AACnC,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AAED,EAAA,OAAO,IAAI,MAAM,MAAA,EAAQ;AAAA,IACvB,GAAA,CAAI,QAAQ,IAAA,EAAM;AAChB,MAAA,IAAI,IAAA,KAAS,QAAQ,OAAO,SAAA;AAC5B,MAAA,OAAQ,OAAe,IAAI,CAAA;AAAA,IAC7B;AAAA,GACD,CAAA;AACH","file":"openai.js","sourcesContent":["import { compress } from \"../compress.js\";\nimport type { CompressOptions, OpenAIMessage } from \"../types.js\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface OpenAILike {\n chat: {\n completions: {\n create: (params: any) => any;\n };\n };\n [key: string]: any;\n}\n\n/**\n * Wrap an OpenAI client to auto-compress messages before each request.\n *\n * Intercepts `client.chat.completions.create()` only. All other methods\n * (embeddings, images, audio, etc.) pass through unchanged.\n *\n * @example\n * ```typescript\n * import { withHeadroom } from 'headroom-ai/openai';\n * import OpenAI from 'openai';\n *\n * const client = withHeadroom(new OpenAI());\n * const response = await client.chat.completions.create({\n * model: 'gpt-4o',\n * messages: longConversation,\n * });\n * ```\n */\nexport function withHeadroom<T extends OpenAILike>(\n client: T,\n options: CompressOptions = {},\n): T {\n const originalCreate = client.chat.completions.create.bind(\n client.chat.completions,\n );\n\n const compressedCreate = async (params: any) => {\n const messages: OpenAIMessage[] = params.messages;\n const model = options.model ?? params.model ?? \"gpt-4o\";\n\n const result = await compress(messages, {\n stack: \"adapter_ts_openai\",\n ...options,\n model,\n });\n\n return originalCreate({\n ...params,\n messages: result.messages,\n });\n };\n\n const completionsProxy = new Proxy(client.chat.completions, {\n get(target, prop) {\n if (prop === \"create\") return compressedCreate;\n return (target as any)[prop];\n },\n });\n\n const chatProxy = new Proxy(client.chat, {\n get(target, prop) {\n if (prop === \"completions\") return completionsProxy;\n return (target as any)[prop];\n },\n });\n\n return new Proxy(client, {\n get(target, prop) {\n if (prop === \"chat\") return chatProxy;\n return (target as any)[prop];\n },\n }) as T;\n}\n"]}
@@ -1,8 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var chunk3N25JEWK_cjs = require('../chunk-3N25JEWK.cjs');
3
+ var chunkR6FB52AD_cjs = require('../chunk-R6FB52AD.cjs');
4
+ var module$1 = require('module');
4
5
 
5
- // src/adapters/vercel-ai.ts
6
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
6
7
  function headroomMiddleware(options = {}) {
7
8
  return {
8
9
  transformParams: async ({
@@ -11,25 +12,49 @@ function headroomMiddleware(options = {}) {
11
12
  const prompt = params.prompt;
12
13
  if (!prompt || prompt.length === 0) return params;
13
14
  const model = options.model ?? params.modelId ?? "gpt-4o";
14
- const openaiMessages = chunk3N25JEWK_cjs.vercelToOpenAI(prompt);
15
- const result = await chunk3N25JEWK_cjs.compress(openaiMessages, { ...options, model });
15
+ const openaiMessages = chunkR6FB52AD_cjs.vercelToOpenAI(prompt);
16
+ const result = await chunkR6FB52AD_cjs.compress(openaiMessages, {
17
+ stack: "adapter_ts_vercel_ai",
18
+ ...options,
19
+ model
20
+ });
16
21
  if (!result.compressed) return params;
17
- const compressedPrompt = chunk3N25JEWK_cjs.openAIToVercel(result.messages);
22
+ const compressedPrompt = chunkR6FB52AD_cjs.openAIToVercel(result.messages);
18
23
  return { ...params, prompt: compressedPrompt };
19
24
  }
20
25
  };
21
26
  }
22
27
  async function compressVercelMessages(messages, options = {}) {
23
- const openaiMessages = chunk3N25JEWK_cjs.vercelToOpenAI(messages);
24
- const result = await chunk3N25JEWK_cjs.compress(openaiMessages, options);
25
- const vercelMessages = chunk3N25JEWK_cjs.openAIToVercel(result.messages);
28
+ const openaiMessages = chunkR6FB52AD_cjs.vercelToOpenAI(messages);
29
+ const result = await chunkR6FB52AD_cjs.compress(openaiMessages, {
30
+ stack: "adapter_ts_vercel_ai",
31
+ ...options
32
+ });
33
+ const vercelMessages = chunkR6FB52AD_cjs.openAIToVercel(result.messages);
26
34
  return {
27
35
  ...result,
28
36
  messages: vercelMessages
29
37
  };
30
38
  }
39
+ function withHeadroom(model, options = {}) {
40
+ let wrapLanguageModel;
41
+ try {
42
+ const require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vercel-ai.cjs', document.baseURI).href)));
43
+ const ai = require2("ai");
44
+ wrapLanguageModel = ai.wrapLanguageModel;
45
+ } catch {
46
+ throw new Error(
47
+ 'withHeadroom() requires the "ai" package. Install it with: npm install ai'
48
+ );
49
+ }
50
+ return wrapLanguageModel({
51
+ model,
52
+ middleware: headroomMiddleware(options)
53
+ });
54
+ }
31
55
 
32
56
  exports.compressVercelMessages = compressVercelMessages;
33
57
  exports.headroomMiddleware = headroomMiddleware;
58
+ exports.withHeadroom = withHeadroom;
34
59
  //# sourceMappingURL=vercel-ai.cjs.map
35
60
  //# sourceMappingURL=vercel-ai.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/vercel-ai.ts"],"names":["vercelToOpenAI","compress","openAIToVercel"],"mappings":";;;;;AAuBO,SAAS,kBAAA,CAAmB,OAAA,GAA2B,EAAC,EAAG;AAChE,EAAA,OAAO;AAAA,IACL,iBAAiB,OAAO;AAAA,MACtB;AAAA,KACF,KAIM;AACJ,MAAA,MAAM,SAA0B,MAAA,CAAO,MAAA;AACvC,MAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,GAAG,OAAO,MAAA;AAE3C,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,OAAA,IAAW,QAAA;AAGjD,MAAA,MAAM,cAAA,GAAiBA,iCAAe,MAAM,CAAA;AAG5C,MAAA,MAAM,MAAA,GAAS,MAAMC,0BAAA,CAAS,cAAA,EAAgB,EAAE,GAAG,OAAA,EAAS,OAAO,CAAA;AAEnE,MAAA,IAAI,CAAC,MAAA,CAAO,UAAA,EAAY,OAAO,MAAA;AAG/B,MAAA,MAAM,gBAAA,GAAmBC,gCAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAEvD,MAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ,gBAAA,EAAiB;AAAA,IAC/C;AAAA,GACF;AACF;AAMA,eAAsB,sBAAA,CACpB,QAAA,EACA,OAAA,GAA2B,EAAC,EAC6B;AACzD,EAAA,MAAM,cAAA,GAAiBF,iCAAe,QAAQ,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,MAAMC,0BAAA,CAAS,cAAA,EAAgB,OAAO,CAAA;AACrD,EAAA,MAAM,cAAA,GAAiBC,gCAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAErD,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,QAAA,EAAU;AAAA,GACZ;AACF","file":"vercel-ai.cjs","sourcesContent":["import { compress } from \"../compress.js\";\nimport type { CompressOptions, CompressResult } from \"../types.js\";\nimport { vercelToOpenAI, openAIToVercel } from \"../utils/format.js\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype VercelMessage = any;\n\n/**\n * Vercel AI SDK LanguageModelV3Middleware that compresses messages\n * before they reach the LLM.\n *\n * @example\n * ```typescript\n * import { headroomMiddleware } from 'headroom-ai/vercel-ai';\n * import { wrapLanguageModel } from 'ai';\n * import { openai } from '@ai-sdk/openai';\n *\n * const model = wrapLanguageModel({\n * model: openai('gpt-4o'),\n * middleware: headroomMiddleware(),\n * });\n * ```\n */\nexport function headroomMiddleware(options: CompressOptions = {}) {\n return {\n transformParams: async ({\n params,\n }: {\n params: any;\n model: any;\n type: string;\n }) => {\n const prompt: VercelMessage[] = params.prompt;\n if (!prompt || prompt.length === 0) return params;\n\n const model = options.model ?? params.modelId ?? \"gpt-4o\";\n\n // Convert Vercel format → OpenAI format\n const openaiMessages = vercelToOpenAI(prompt);\n\n // Compress via Headroom\n const result = await compress(openaiMessages, { ...options, model });\n\n if (!result.compressed) return params;\n\n // Convert back to Vercel format\n const compressedPrompt = openAIToVercel(result.messages);\n\n return { ...params, prompt: compressedPrompt };\n },\n };\n}\n\n/**\n * Standalone: compress Vercel AI SDK ModelMessage[] directly.\n * Returns compressed messages in Vercel format + compression stats.\n */\nexport async function compressVercelMessages(\n messages: VercelMessage[],\n options: CompressOptions = {},\n): Promise<CompressResult & { messages: VercelMessage[] }> {\n const openaiMessages = vercelToOpenAI(messages);\n const result = await compress(openaiMessages, options);\n const vercelMessages = openAIToVercel(result.messages);\n\n return {\n ...result,\n messages: vercelMessages,\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/adapters/vercel-ai.ts"],"names":["vercelToOpenAI","compress","openAIToVercel","require","createRequire"],"mappings":";;;;;;AAsCO,SAAS,kBAAA,CAAmB,OAAA,GAA2B,EAAC,EAAG;AAChE,EAAA,OAAO;AAAA,IACL,iBAAiB,OAAO;AAAA,MACtB;AAAA,KACF,KAIM;AACJ,MAAA,MAAM,SAA0B,MAAA,CAAO,MAAA;AACvC,MAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,GAAG,OAAO,MAAA;AAE3C,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,OAAA,IAAW,QAAA;AAGjD,MAAA,MAAM,cAAA,GAAiBA,iCAAe,MAAM,CAAA;AAG5C,MAAA,MAAM,MAAA,GAAS,MAAMC,0BAAA,CAAS,cAAA,EAAgB;AAAA,QAC5C,KAAA,EAAO,sBAAA;AAAA,QACP,GAAG,OAAA;AAAA,QACH;AAAA,OACD,CAAA;AAED,MAAA,IAAI,CAAC,MAAA,CAAO,UAAA,EAAY,OAAO,MAAA;AAG/B,MAAA,MAAM,gBAAA,GAAmBC,gCAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAEvD,MAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ,gBAAA,EAAiB;AAAA,IAC/C;AAAA,GACF;AACF;AAMA,eAAsB,sBAAA,CACpB,QAAA,EACA,OAAA,GAA2B,EAAC,EAC6B;AACzD,EAAA,MAAM,cAAA,GAAiBF,iCAAe,QAAQ,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,MAAMC,0BAAA,CAAS,cAAA,EAAgB;AAAA,IAC5C,KAAA,EAAO,sBAAA;AAAA,IACP,GAAG;AAAA,GACJ,CAAA;AACD,EAAA,MAAM,cAAA,GAAiBC,gCAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAErD,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,QAAA,EAAU;AAAA,GACZ;AACF;AAgBO,SAAS,YAAA,CACd,KAAA,EACA,OAAA,GAA2B,EAAC,EACzB;AACH,EAAA,IAAI,iBAAA;AAKJ,EAAA,IAAI;AACF,IAAA,MAAMC,QAAAA,GAAUC,sBAAA,CAAc,+PAAe,CAAA;AAC7C,IAAA,MAAM,EAAA,GAAKD,SAAQ,IAAI,CAAA;AACvB,IAAA,iBAAA,GAAoB,EAAA,CAAG,iBAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,iBAAA,CAAkB;AAAA,IACvB,KAAA;AAAA,IACA,UAAA,EAAY,mBAAmB,OAAO;AAAA,GACvC,CAAA;AACH","file":"vercel-ai.cjs","sourcesContent":["import { createRequire } from \"node:module\";\nimport { compress } from \"../compress.js\";\nimport type { CompressOptions, CompressResult } from \"../types.js\";\nimport { vercelToOpenAI, openAIToVercel } from \"../utils/format.js\";\n\n/**\n * Minimal structural type for Vercel AI SDK language models.\n * Compatible with both LanguageModelV1 (@ai-sdk/provider <=1.x)\n * and LanguageModelV3 (@ai-sdk/provider >=2.x).\n */\ninterface LanguageModel {\n readonly specificationVersion: string;\n readonly provider: string;\n readonly modelId: string;\n doGenerate: (...args: any[]) => any;\n doStream: (...args: any[]) => any;\n [key: string]: any;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype VercelMessage = any;\n\n/**\n * Vercel AI SDK LanguageModelV3Middleware that compresses messages\n * before they reach the LLM.\n *\n * @example\n * ```typescript\n * import { headroomMiddleware } from 'headroom-ai/vercel-ai';\n * import { wrapLanguageModel } from 'ai';\n * import { openai } from '@ai-sdk/openai';\n *\n * const model = wrapLanguageModel({\n * model: openai('gpt-4o'),\n * middleware: headroomMiddleware(),\n * });\n * ```\n */\nexport function headroomMiddleware(options: CompressOptions = {}) {\n return {\n transformParams: async ({\n params,\n }: {\n params: any;\n model: any;\n type: string;\n }) => {\n const prompt: VercelMessage[] = params.prompt;\n if (!prompt || prompt.length === 0) return params;\n\n const model = options.model ?? params.modelId ?? \"gpt-4o\";\n\n // Convert Vercel format → OpenAI format\n const openaiMessages = vercelToOpenAI(prompt);\n\n // Compress via Headroom\n const result = await compress(openaiMessages, {\n stack: \"adapter_ts_vercel_ai\",\n ...options,\n model,\n });\n\n if (!result.compressed) return params;\n\n // Convert back to Vercel format\n const compressedPrompt = openAIToVercel(result.messages);\n\n return { ...params, prompt: compressedPrompt };\n },\n };\n}\n\n/**\n * Standalone: compress Vercel AI SDK ModelMessage[] directly.\n * Returns compressed messages in Vercel format + compression stats.\n */\nexport async function compressVercelMessages(\n messages: VercelMessage[],\n options: CompressOptions = {},\n): Promise<CompressResult & { messages: VercelMessage[] }> {\n const openaiMessages = vercelToOpenAI(messages);\n const result = await compress(openaiMessages, {\n stack: \"adapter_ts_vercel_ai\",\n ...options,\n });\n const vercelMessages = openAIToVercel(result.messages);\n\n return {\n ...result,\n messages: vercelMessages,\n };\n}\n\n/**\n * Wrap a Vercel AI SDK language model with Headroom compression.\n * Convenience wrapper around `wrapLanguageModel` + `headroomMiddleware`.\n *\n * @example\n * ```typescript\n * import { withHeadroom } from 'headroom-ai/vercel-ai';\n * import { openai } from '@ai-sdk/openai';\n * import { generateText } from 'ai';\n *\n * const model = withHeadroom(openai('gpt-4o'));\n * const { text } = await generateText({ model, messages });\n * ```\n */\nexport function withHeadroom<T extends LanguageModel>(\n model: T,\n options: CompressOptions = {},\n): T {\n let wrapLanguageModel: (opts: {\n model: T;\n middleware: any;\n }) => T;\n\n try {\n const require = createRequire(import.meta.url);\n const ai = require(\"ai\");\n wrapLanguageModel = ai.wrapLanguageModel;\n } catch {\n throw new Error(\n 'withHeadroom() requires the \"ai\" package. Install it with: npm install ai',\n );\n }\n\n return wrapLanguageModel({\n model,\n middleware: headroomMiddleware(options),\n });\n}\n"]}
@@ -1,5 +1,18 @@
1
- import { C as CompressOptions, a as CompressResult } from '../types-DQtcLXq3.cjs';
1
+ import { C as CompressOptions, a as CompressResult } from '../types-BTrX7__W.cjs';
2
2
 
3
+ /**
4
+ * Minimal structural type for Vercel AI SDK language models.
5
+ * Compatible with both LanguageModelV1 (@ai-sdk/provider <=1.x)
6
+ * and LanguageModelV3 (@ai-sdk/provider >=2.x).
7
+ */
8
+ interface LanguageModel {
9
+ readonly specificationVersion: string;
10
+ readonly provider: string;
11
+ readonly modelId: string;
12
+ doGenerate: (...args: any[]) => any;
13
+ doStream: (...args: any[]) => any;
14
+ [key: string]: any;
15
+ }
3
16
  type VercelMessage = any;
4
17
  /**
5
18
  * Vercel AI SDK LanguageModelV3Middleware that compresses messages
@@ -31,5 +44,20 @@ declare function headroomMiddleware(options?: CompressOptions): {
31
44
  declare function compressVercelMessages(messages: VercelMessage[], options?: CompressOptions): Promise<CompressResult & {
32
45
  messages: VercelMessage[];
33
46
  }>;
47
+ /**
48
+ * Wrap a Vercel AI SDK language model with Headroom compression.
49
+ * Convenience wrapper around `wrapLanguageModel` + `headroomMiddleware`.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * import { withHeadroom } from 'headroom-ai/vercel-ai';
54
+ * import { openai } from '@ai-sdk/openai';
55
+ * import { generateText } from 'ai';
56
+ *
57
+ * const model = withHeadroom(openai('gpt-4o'));
58
+ * const { text } = await generateText({ model, messages });
59
+ * ```
60
+ */
61
+ declare function withHeadroom<T extends LanguageModel>(model: T, options?: CompressOptions): T;
34
62
 
35
- export { compressVercelMessages, headroomMiddleware };
63
+ export { compressVercelMessages, headroomMiddleware, withHeadroom };
@@ -1,5 +1,18 @@
1
- import { C as CompressOptions, a as CompressResult } from '../types-DQtcLXq3.js';
1
+ import { C as CompressOptions, a as CompressResult } from '../types-BTrX7__W.js';
2
2
 
3
+ /**
4
+ * Minimal structural type for Vercel AI SDK language models.
5
+ * Compatible with both LanguageModelV1 (@ai-sdk/provider <=1.x)
6
+ * and LanguageModelV3 (@ai-sdk/provider >=2.x).
7
+ */
8
+ interface LanguageModel {
9
+ readonly specificationVersion: string;
10
+ readonly provider: string;
11
+ readonly modelId: string;
12
+ doGenerate: (...args: any[]) => any;
13
+ doStream: (...args: any[]) => any;
14
+ [key: string]: any;
15
+ }
3
16
  type VercelMessage = any;
4
17
  /**
5
18
  * Vercel AI SDK LanguageModelV3Middleware that compresses messages
@@ -31,5 +44,20 @@ declare function headroomMiddleware(options?: CompressOptions): {
31
44
  declare function compressVercelMessages(messages: VercelMessage[], options?: CompressOptions): Promise<CompressResult & {
32
45
  messages: VercelMessage[];
33
46
  }>;
47
+ /**
48
+ * Wrap a Vercel AI SDK language model with Headroom compression.
49
+ * Convenience wrapper around `wrapLanguageModel` + `headroomMiddleware`.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * import { withHeadroom } from 'headroom-ai/vercel-ai';
54
+ * import { openai } from '@ai-sdk/openai';
55
+ * import { generateText } from 'ai';
56
+ *
57
+ * const model = withHeadroom(openai('gpt-4o'));
58
+ * const { text } = await generateText({ model, messages });
59
+ * ```
60
+ */
61
+ declare function withHeadroom<T extends LanguageModel>(model: T, options?: CompressOptions): T;
34
62
 
35
- export { compressVercelMessages, headroomMiddleware };
63
+ export { compressVercelMessages, headroomMiddleware, withHeadroom };
@@ -1,6 +1,6 @@
1
- import { vercelToOpenAI, compress, openAIToVercel } from '../chunk-YTTW7S2Q.js';
1
+ import { vercelToOpenAI, compress, openAIToVercel } from '../chunk-7AJIWIPP.js';
2
+ import { createRequire } from 'module';
2
3
 
3
- // src/adapters/vercel-ai.ts
4
4
  function headroomMiddleware(options = {}) {
5
5
  return {
6
6
  transformParams: async ({
@@ -10,7 +10,11 @@ function headroomMiddleware(options = {}) {
10
10
  if (!prompt || prompt.length === 0) return params;
11
11
  const model = options.model ?? params.modelId ?? "gpt-4o";
12
12
  const openaiMessages = vercelToOpenAI(prompt);
13
- const result = await compress(openaiMessages, { ...options, model });
13
+ const result = await compress(openaiMessages, {
14
+ stack: "adapter_ts_vercel_ai",
15
+ ...options,
16
+ model
17
+ });
14
18
  if (!result.compressed) return params;
15
19
  const compressedPrompt = openAIToVercel(result.messages);
16
20
  return { ...params, prompt: compressedPrompt };
@@ -19,14 +23,33 @@ function headroomMiddleware(options = {}) {
19
23
  }
20
24
  async function compressVercelMessages(messages, options = {}) {
21
25
  const openaiMessages = vercelToOpenAI(messages);
22
- const result = await compress(openaiMessages, options);
26
+ const result = await compress(openaiMessages, {
27
+ stack: "adapter_ts_vercel_ai",
28
+ ...options
29
+ });
23
30
  const vercelMessages = openAIToVercel(result.messages);
24
31
  return {
25
32
  ...result,
26
33
  messages: vercelMessages
27
34
  };
28
35
  }
36
+ function withHeadroom(model, options = {}) {
37
+ let wrapLanguageModel;
38
+ try {
39
+ const require2 = createRequire(import.meta.url);
40
+ const ai = require2("ai");
41
+ wrapLanguageModel = ai.wrapLanguageModel;
42
+ } catch {
43
+ throw new Error(
44
+ 'withHeadroom() requires the "ai" package. Install it with: npm install ai'
45
+ );
46
+ }
47
+ return wrapLanguageModel({
48
+ model,
49
+ middleware: headroomMiddleware(options)
50
+ });
51
+ }
29
52
 
30
- export { compressVercelMessages, headroomMiddleware };
53
+ export { compressVercelMessages, headroomMiddleware, withHeadroom };
31
54
  //# sourceMappingURL=vercel-ai.js.map
32
55
  //# sourceMappingURL=vercel-ai.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/vercel-ai.ts"],"names":[],"mappings":";;;AAuBO,SAAS,kBAAA,CAAmB,OAAA,GAA2B,EAAC,EAAG;AAChE,EAAA,OAAO;AAAA,IACL,iBAAiB,OAAO;AAAA,MACtB;AAAA,KACF,KAIM;AACJ,MAAA,MAAM,SAA0B,MAAA,CAAO,MAAA;AACvC,MAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,GAAG,OAAO,MAAA;AAE3C,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,OAAA,IAAW,QAAA;AAGjD,MAAA,MAAM,cAAA,GAAiB,eAAe,MAAM,CAAA;AAG5C,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,cAAA,EAAgB,EAAE,GAAG,OAAA,EAAS,OAAO,CAAA;AAEnE,MAAA,IAAI,CAAC,MAAA,CAAO,UAAA,EAAY,OAAO,MAAA;AAG/B,MAAA,MAAM,gBAAA,GAAmB,cAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAEvD,MAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ,gBAAA,EAAiB;AAAA,IAC/C;AAAA,GACF;AACF;AAMA,eAAsB,sBAAA,CACpB,QAAA,EACA,OAAA,GAA2B,EAAC,EAC6B;AACzD,EAAA,MAAM,cAAA,GAAiB,eAAe,QAAQ,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,cAAA,EAAgB,OAAO,CAAA;AACrD,EAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAErD,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,QAAA,EAAU;AAAA,GACZ;AACF","file":"vercel-ai.js","sourcesContent":["import { compress } from \"../compress.js\";\nimport type { CompressOptions, CompressResult } from \"../types.js\";\nimport { vercelToOpenAI, openAIToVercel } from \"../utils/format.js\";\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype VercelMessage = any;\n\n/**\n * Vercel AI SDK LanguageModelV3Middleware that compresses messages\n * before they reach the LLM.\n *\n * @example\n * ```typescript\n * import { headroomMiddleware } from 'headroom-ai/vercel-ai';\n * import { wrapLanguageModel } from 'ai';\n * import { openai } from '@ai-sdk/openai';\n *\n * const model = wrapLanguageModel({\n * model: openai('gpt-4o'),\n * middleware: headroomMiddleware(),\n * });\n * ```\n */\nexport function headroomMiddleware(options: CompressOptions = {}) {\n return {\n transformParams: async ({\n params,\n }: {\n params: any;\n model: any;\n type: string;\n }) => {\n const prompt: VercelMessage[] = params.prompt;\n if (!prompt || prompt.length === 0) return params;\n\n const model = options.model ?? params.modelId ?? \"gpt-4o\";\n\n // Convert Vercel format → OpenAI format\n const openaiMessages = vercelToOpenAI(prompt);\n\n // Compress via Headroom\n const result = await compress(openaiMessages, { ...options, model });\n\n if (!result.compressed) return params;\n\n // Convert back to Vercel format\n const compressedPrompt = openAIToVercel(result.messages);\n\n return { ...params, prompt: compressedPrompt };\n },\n };\n}\n\n/**\n * Standalone: compress Vercel AI SDK ModelMessage[] directly.\n * Returns compressed messages in Vercel format + compression stats.\n */\nexport async function compressVercelMessages(\n messages: VercelMessage[],\n options: CompressOptions = {},\n): Promise<CompressResult & { messages: VercelMessage[] }> {\n const openaiMessages = vercelToOpenAI(messages);\n const result = await compress(openaiMessages, options);\n const vercelMessages = openAIToVercel(result.messages);\n\n return {\n ...result,\n messages: vercelMessages,\n };\n}\n"]}
1
+ {"version":3,"sources":["../../src/adapters/vercel-ai.ts"],"names":["require"],"mappings":";;;AAsCO,SAAS,kBAAA,CAAmB,OAAA,GAA2B,EAAC,EAAG;AAChE,EAAA,OAAO;AAAA,IACL,iBAAiB,OAAO;AAAA,MACtB;AAAA,KACF,KAIM;AACJ,MAAA,MAAM,SAA0B,MAAA,CAAO,MAAA;AACvC,MAAA,IAAI,CAAC,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,GAAG,OAAO,MAAA;AAE3C,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,IAAS,MAAA,CAAO,OAAA,IAAW,QAAA;AAGjD,MAAA,MAAM,cAAA,GAAiB,eAAe,MAAM,CAAA;AAG5C,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,cAAA,EAAgB;AAAA,QAC5C,KAAA,EAAO,sBAAA;AAAA,QACP,GAAG,OAAA;AAAA,QACH;AAAA,OACD,CAAA;AAED,MAAA,IAAI,CAAC,MAAA,CAAO,UAAA,EAAY,OAAO,MAAA;AAG/B,MAAA,MAAM,gBAAA,GAAmB,cAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAEvD,MAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,MAAA,EAAQ,gBAAA,EAAiB;AAAA,IAC/C;AAAA,GACF;AACF;AAMA,eAAsB,sBAAA,CACpB,QAAA,EACA,OAAA,GAA2B,EAAC,EAC6B;AACzD,EAAA,MAAM,cAAA,GAAiB,eAAe,QAAQ,CAAA;AAC9C,EAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,cAAA,EAAgB;AAAA,IAC5C,KAAA,EAAO,sBAAA;AAAA,IACP,GAAG;AAAA,GACJ,CAAA;AACD,EAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,MAAA,CAAO,QAAQ,CAAA;AAErD,EAAA,OAAO;AAAA,IACL,GAAG,MAAA;AAAA,IACH,QAAA,EAAU;AAAA,GACZ;AACF;AAgBO,SAAS,YAAA,CACd,KAAA,EACA,OAAA,GAA2B,EAAC,EACzB;AACH,EAAA,IAAI,iBAAA;AAKJ,EAAA,IAAI;AACF,IAAA,MAAMA,QAAAA,GAAU,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAC7C,IAAA,MAAM,EAAA,GAAKA,SAAQ,IAAI,CAAA;AACvB,IAAA,iBAAA,GAAoB,EAAA,CAAG,iBAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,iBAAA,CAAkB;AAAA,IACvB,KAAA;AAAA,IACA,UAAA,EAAY,mBAAmB,OAAO;AAAA,GACvC,CAAA;AACH","file":"vercel-ai.js","sourcesContent":["import { createRequire } from \"node:module\";\nimport { compress } from \"../compress.js\";\nimport type { CompressOptions, CompressResult } from \"../types.js\";\nimport { vercelToOpenAI, openAIToVercel } from \"../utils/format.js\";\n\n/**\n * Minimal structural type for Vercel AI SDK language models.\n * Compatible with both LanguageModelV1 (@ai-sdk/provider <=1.x)\n * and LanguageModelV3 (@ai-sdk/provider >=2.x).\n */\ninterface LanguageModel {\n readonly specificationVersion: string;\n readonly provider: string;\n readonly modelId: string;\n doGenerate: (...args: any[]) => any;\n doStream: (...args: any[]) => any;\n [key: string]: any;\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype VercelMessage = any;\n\n/**\n * Vercel AI SDK LanguageModelV3Middleware that compresses messages\n * before they reach the LLM.\n *\n * @example\n * ```typescript\n * import { headroomMiddleware } from 'headroom-ai/vercel-ai';\n * import { wrapLanguageModel } from 'ai';\n * import { openai } from '@ai-sdk/openai';\n *\n * const model = wrapLanguageModel({\n * model: openai('gpt-4o'),\n * middleware: headroomMiddleware(),\n * });\n * ```\n */\nexport function headroomMiddleware(options: CompressOptions = {}) {\n return {\n transformParams: async ({\n params,\n }: {\n params: any;\n model: any;\n type: string;\n }) => {\n const prompt: VercelMessage[] = params.prompt;\n if (!prompt || prompt.length === 0) return params;\n\n const model = options.model ?? params.modelId ?? \"gpt-4o\";\n\n // Convert Vercel format → OpenAI format\n const openaiMessages = vercelToOpenAI(prompt);\n\n // Compress via Headroom\n const result = await compress(openaiMessages, {\n stack: \"adapter_ts_vercel_ai\",\n ...options,\n model,\n });\n\n if (!result.compressed) return params;\n\n // Convert back to Vercel format\n const compressedPrompt = openAIToVercel(result.messages);\n\n return { ...params, prompt: compressedPrompt };\n },\n };\n}\n\n/**\n * Standalone: compress Vercel AI SDK ModelMessage[] directly.\n * Returns compressed messages in Vercel format + compression stats.\n */\nexport async function compressVercelMessages(\n messages: VercelMessage[],\n options: CompressOptions = {},\n): Promise<CompressResult & { messages: VercelMessage[] }> {\n const openaiMessages = vercelToOpenAI(messages);\n const result = await compress(openaiMessages, {\n stack: \"adapter_ts_vercel_ai\",\n ...options,\n });\n const vercelMessages = openAIToVercel(result.messages);\n\n return {\n ...result,\n messages: vercelMessages,\n };\n}\n\n/**\n * Wrap a Vercel AI SDK language model with Headroom compression.\n * Convenience wrapper around `wrapLanguageModel` + `headroomMiddleware`.\n *\n * @example\n * ```typescript\n * import { withHeadroom } from 'headroom-ai/vercel-ai';\n * import { openai } from '@ai-sdk/openai';\n * import { generateText } from 'ai';\n *\n * const model = withHeadroom(openai('gpt-4o'));\n * const { text } = await generateText({ model, messages });\n * ```\n */\nexport function withHeadroom<T extends LanguageModel>(\n model: T,\n options: CompressOptions = {},\n): T {\n let wrapLanguageModel: (opts: {\n model: T;\n middleware: any;\n }) => T;\n\n try {\n const require = createRequire(import.meta.url);\n const ai = require(\"ai\");\n wrapLanguageModel = ai.wrapLanguageModel;\n } catch {\n throw new Error(\n 'withHeadroom() requires the \"ai\" package. Install it with: npm install ai',\n );\n }\n\n return wrapLanguageModel({\n model,\n middleware: headroomMiddleware(options),\n });\n}\n"]}