@usagetap/sdk 1.1.0 → 1.3.1

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 (50) hide show
  1. package/README.md +200 -201
  2. package/dist/adapters/anthropic.cjs +1676 -6
  3. package/dist/adapters/anthropic.cjs.map +1 -1
  4. package/dist/adapters/anthropic.d.cts +39 -2
  5. package/dist/adapters/anthropic.d.ts +39 -2
  6. package/dist/adapters/anthropic.mjs +1675 -7
  7. package/dist/adapters/anthropic.mjs.map +1 -1
  8. package/dist/adapters/openai.cjs +1726 -6
  9. package/dist/adapters/openai.cjs.map +1 -1
  10. package/dist/adapters/openai.d.cts +46 -2
  11. package/dist/adapters/openai.d.ts +46 -2
  12. package/dist/adapters/openai.mjs +1725 -7
  13. package/dist/adapters/openai.mjs.map +1 -1
  14. package/dist/adapters/openrouter.cjs.map +1 -1
  15. package/dist/adapters/openrouter.d.cts +1 -1
  16. package/dist/adapters/openrouter.d.ts +1 -1
  17. package/dist/adapters/openrouter.mjs.map +1 -1
  18. package/dist/anthropic/index.cjs +1676 -6
  19. package/dist/anthropic/index.cjs.map +1 -1
  20. package/dist/anthropic/index.d.cts +2 -2
  21. package/dist/anthropic/index.d.ts +2 -2
  22. package/dist/anthropic/index.mjs +1675 -7
  23. package/dist/anthropic/index.mjs.map +1 -1
  24. package/dist/{client-BA-QlnRq.d.cts → client-BD8O2J8Z.d.cts} +106 -11
  25. package/dist/{client-BA-QlnRq.d.ts → client-BD8O2J8Z.d.ts} +106 -11
  26. package/dist/express/index.cjs +86 -1
  27. package/dist/express/index.cjs.map +1 -1
  28. package/dist/express/index.d.cts +1 -1
  29. package/dist/express/index.d.ts +1 -1
  30. package/dist/express/index.mjs +86 -1
  31. package/dist/express/index.mjs.map +1 -1
  32. package/dist/index.cjs +263 -39
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +3 -3
  35. package/dist/index.d.ts +3 -3
  36. package/dist/index.mjs +262 -40
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/openai/index.cjs +1726 -6
  39. package/dist/openai/index.cjs.map +1 -1
  40. package/dist/openai/index.d.cts +2 -2
  41. package/dist/openai/index.d.ts +2 -2
  42. package/dist/openai/index.mjs +1725 -7
  43. package/dist/openai/index.mjs.map +1 -1
  44. package/dist/openrouter/index.cjs +3024 -0
  45. package/dist/openrouter/index.cjs.map +1 -0
  46. package/dist/openrouter/index.d.cts +4 -0
  47. package/dist/openrouter/index.d.ts +4 -0
  48. package/dist/openrouter/index.mjs +3019 -0
  49. package/dist/openrouter/index.mjs.map +1 -0
  50. package/package.json +102 -44
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { U as UsageTapClient, B as BeginCallRequest } from './client-BA-QlnRq.cjs';
2
- export { _ as AllowedEntitlements, H as BalanceSummary, k as BeginCallOptions, c as BeginCallResponseBody, v as ChangePlanOptions, w as ChangePlanRequest, x as ChangePlanResponseBody, y as ChangePlanStrategy, s as CheckUsageOptions, t as CheckUsageRequest, u as CheckUsageResponseBody, C as CreateCustomerOptions, q as CreateCustomerRequest, r as CreateCustomerResponseBody, D as CustomMeterSlot, F as EndCallOptions, E as EndCallRequest, G as EndCallResponseBody, L as EntitlementHints, a9 as IdempotencyMetadata, I as IncrementCustomMeterOptions, z as IncrementCustomMeterRequest, A as IncrementCustomMeterResponseBody, a6 as LimitType, O as MeterSnapshot, N as MeterSummary, Q as MeteredUsage, a8 as ModelHints, M as PlanSummary, i as PromptCompressionInput, m as PromptCompressionOptions, P as PromptCompressionProvider, l as PromptCompressionRequest, n as PromptCompressionResponseBody, j as PromptCompressionResult, o as PromptCompressionStandaloneOptions, a as PromptCompressionTelemetry, T as RateLimitsSnapshot, R as RecordPromptCompressionRequest, X as RemainingRatios, Z as RequestedEntitlements, $ as RetryOptions, Y as RollingCallsRateLimitState, S as SpendVelocitySnapshot, J as SpendVelocityWindow, K as SpendVelocityWindowKey, a7 as SubscriptionSnapshot, aa as UsageMetricEvent, a0 as UsageTapClientOptions, a1 as UsageTapErrorResponse, a4 as UsageTapLogEntry, a2 as UsageTapResultEnvelope, a3 as UsageTapResultStatus, b as UsageTapSuccessResponse, V as VendorHints, a5 as WithUsageContext, W as WithUsageOptions, d as compressPrompt, e as compressPromptHeuristic, f as compressPromptToon, g as estimatePromptTokens, p as protect, h as protectPromptText } from './client-BA-QlnRq.cjs';
1
+ import { U as UsageTapClient, B as BeginCallRequest } from './client-BD8O2J8Z.cjs';
2
+ export { a7 as AllowedEntitlements, T as BalanceSummary, s as BeginCallOptions, c as BeginCallResponseBody, G as ChangePlanOptions, H as ChangePlanRequest, I as ChangePlanResponseBody, J as ChangePlanStrategy, A as CheckUsageOptions, D as CheckUsageRequest, F as CheckUsageResponseBody, C as CreateCustomerOptions, y as CreateCustomerRequest, z as CreateCustomerResponseBody, O as CustomMeterSlot, Q as EndCallOptions, E as EndCallRequest, S as EndCallResponseBody, _ as EntitlementHints, ai as IdempotencyMetadata, K as IncrementCustomMeterOptions, L as IncrementCustomMeterRequest, N as IncrementCustomMeterResponseBody, af as LimitType, M as MeterRequest, a1 as MeterSnapshot, a0 as MeterSummary, a2 as MeteredUsage, ah as ModelHints, $ as PlanSummary, l as PromptCompressionInput, o as PromptCompressionMessageRole, m as PromptCompressionMessagesAggressiveness, n as PromptCompressionMessagesInput, v as PromptCompressionMessagesOptions, u as PromptCompressionOptions, P as PromptCompressionProvider, t as PromptCompressionRequest, w as PromptCompressionResponseBody, q as PromptCompressionResult, r as PromptCompressionRoleAggressiveness, x as PromptCompressionStandaloneOptions, a as PromptCompressionTelemetry, a3 as RateLimitsSnapshot, R as RecordPromptCompressionRequest, a4 as RemainingRatios, a6 as RequestedEntitlements, a8 as RetryOptions, a5 as RollingCallsRateLimitState, X as SpendVelocitySnapshot, Y as SpendVelocityWindow, Z as SpendVelocityWindowKey, ag as SubscriptionSnapshot, aj as UsageMetricEvent, a9 as UsageTapClientOptions, d as UsageTapCompressOptions, e as UsageTapCompressResult, aa as UsageTapErrorResponse, ad as UsageTapLogEntry, ab as UsageTapResultEnvelope, ac as UsageTapResultStatus, b as UsageTapSuccessResponse, V as VendorHints, ae as WithUsageContext, W as WithUsageOptions, f as compressPrompt, h as compressPromptHeuristic, g as compressPromptMessages, i as compressPromptToon, j as estimatePromptTokens, p as protect, k as protectPromptText } from './client-BD8O2J8Z.cjs';
3
3
 
4
4
  type UsageTapErrorCode = "USAGETAP_BROWSER_RUNTIME" | "USAGETAP_AUTH_ERROR" | "USAGETAP_BAD_REQUEST" | "USAGETAP_INVALID_RESPONSE" | "USAGETAP_NETWORK_ERROR" | "USAGETAP_RATE_LIMITED" | "USAGETAP_SERVER_ERROR" | "USAGETAP_RETRY_EXHAUSTED" | "USAGETAP_END_CALL_ERROR";
5
5
  interface UsageTapErrorInit {
@@ -65,4 +65,4 @@ declare function wrapFetch(usageTap: UsageTapClient, options: WrapFetchOptions):
65
65
 
66
66
  declare function createIdempotencyKey(): string;
67
67
 
68
- export { BeginCallRequest, UsageTapClient, UsageTapError, type UsageTapErrorCode, type UsageTapErrorInit, type WrapFetchContext, type WrapFetchOptions, createIdempotencyKey, isUsageTapError, wrapFetch };
68
+ export { BeginCallRequest, UsageTapClient as UsageTap, UsageTapClient, UsageTapError, type UsageTapErrorCode, type UsageTapErrorInit, type WrapFetchContext, type WrapFetchOptions, createIdempotencyKey, isUsageTapError, wrapFetch };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { U as UsageTapClient, B as BeginCallRequest } from './client-BA-QlnRq.js';
2
- export { _ as AllowedEntitlements, H as BalanceSummary, k as BeginCallOptions, c as BeginCallResponseBody, v as ChangePlanOptions, w as ChangePlanRequest, x as ChangePlanResponseBody, y as ChangePlanStrategy, s as CheckUsageOptions, t as CheckUsageRequest, u as CheckUsageResponseBody, C as CreateCustomerOptions, q as CreateCustomerRequest, r as CreateCustomerResponseBody, D as CustomMeterSlot, F as EndCallOptions, E as EndCallRequest, G as EndCallResponseBody, L as EntitlementHints, a9 as IdempotencyMetadata, I as IncrementCustomMeterOptions, z as IncrementCustomMeterRequest, A as IncrementCustomMeterResponseBody, a6 as LimitType, O as MeterSnapshot, N as MeterSummary, Q as MeteredUsage, a8 as ModelHints, M as PlanSummary, i as PromptCompressionInput, m as PromptCompressionOptions, P as PromptCompressionProvider, l as PromptCompressionRequest, n as PromptCompressionResponseBody, j as PromptCompressionResult, o as PromptCompressionStandaloneOptions, a as PromptCompressionTelemetry, T as RateLimitsSnapshot, R as RecordPromptCompressionRequest, X as RemainingRatios, Z as RequestedEntitlements, $ as RetryOptions, Y as RollingCallsRateLimitState, S as SpendVelocitySnapshot, J as SpendVelocityWindow, K as SpendVelocityWindowKey, a7 as SubscriptionSnapshot, aa as UsageMetricEvent, a0 as UsageTapClientOptions, a1 as UsageTapErrorResponse, a4 as UsageTapLogEntry, a2 as UsageTapResultEnvelope, a3 as UsageTapResultStatus, b as UsageTapSuccessResponse, V as VendorHints, a5 as WithUsageContext, W as WithUsageOptions, d as compressPrompt, e as compressPromptHeuristic, f as compressPromptToon, g as estimatePromptTokens, p as protect, h as protectPromptText } from './client-BA-QlnRq.js';
1
+ import { U as UsageTapClient, B as BeginCallRequest } from './client-BD8O2J8Z.js';
2
+ export { a7 as AllowedEntitlements, T as BalanceSummary, s as BeginCallOptions, c as BeginCallResponseBody, G as ChangePlanOptions, H as ChangePlanRequest, I as ChangePlanResponseBody, J as ChangePlanStrategy, A as CheckUsageOptions, D as CheckUsageRequest, F as CheckUsageResponseBody, C as CreateCustomerOptions, y as CreateCustomerRequest, z as CreateCustomerResponseBody, O as CustomMeterSlot, Q as EndCallOptions, E as EndCallRequest, S as EndCallResponseBody, _ as EntitlementHints, ai as IdempotencyMetadata, K as IncrementCustomMeterOptions, L as IncrementCustomMeterRequest, N as IncrementCustomMeterResponseBody, af as LimitType, M as MeterRequest, a1 as MeterSnapshot, a0 as MeterSummary, a2 as MeteredUsage, ah as ModelHints, $ as PlanSummary, l as PromptCompressionInput, o as PromptCompressionMessageRole, m as PromptCompressionMessagesAggressiveness, n as PromptCompressionMessagesInput, v as PromptCompressionMessagesOptions, u as PromptCompressionOptions, P as PromptCompressionProvider, t as PromptCompressionRequest, w as PromptCompressionResponseBody, q as PromptCompressionResult, r as PromptCompressionRoleAggressiveness, x as PromptCompressionStandaloneOptions, a as PromptCompressionTelemetry, a3 as RateLimitsSnapshot, R as RecordPromptCompressionRequest, a4 as RemainingRatios, a6 as RequestedEntitlements, a8 as RetryOptions, a5 as RollingCallsRateLimitState, X as SpendVelocitySnapshot, Y as SpendVelocityWindow, Z as SpendVelocityWindowKey, ag as SubscriptionSnapshot, aj as UsageMetricEvent, a9 as UsageTapClientOptions, d as UsageTapCompressOptions, e as UsageTapCompressResult, aa as UsageTapErrorResponse, ad as UsageTapLogEntry, ab as UsageTapResultEnvelope, ac as UsageTapResultStatus, b as UsageTapSuccessResponse, V as VendorHints, ae as WithUsageContext, W as WithUsageOptions, f as compressPrompt, h as compressPromptHeuristic, g as compressPromptMessages, i as compressPromptToon, j as estimatePromptTokens, p as protect, k as protectPromptText } from './client-BD8O2J8Z.js';
3
3
 
4
4
  type UsageTapErrorCode = "USAGETAP_BROWSER_RUNTIME" | "USAGETAP_AUTH_ERROR" | "USAGETAP_BAD_REQUEST" | "USAGETAP_INVALID_RESPONSE" | "USAGETAP_NETWORK_ERROR" | "USAGETAP_RATE_LIMITED" | "USAGETAP_SERVER_ERROR" | "USAGETAP_RETRY_EXHAUSTED" | "USAGETAP_END_CALL_ERROR";
5
5
  interface UsageTapErrorInit {
@@ -65,4 +65,4 @@ declare function wrapFetch(usageTap: UsageTapClient, options: WrapFetchOptions):
65
65
 
66
66
  declare function createIdempotencyKey(): string;
67
67
 
68
- export { BeginCallRequest, UsageTapClient, UsageTapError, type UsageTapErrorCode, type UsageTapErrorInit, type WrapFetchContext, type WrapFetchOptions, createIdempotencyKey, isUsageTapError, wrapFetch };
68
+ export { BeginCallRequest, UsageTapClient as UsageTap, UsageTapClient, UsageTapError, type UsageTapErrorCode, type UsageTapErrorInit, type WrapFetchContext, type WrapFetchOptions, createIdempotencyKey, isUsageTapError, wrapFetch };
package/dist/index.mjs CHANGED
@@ -117,26 +117,32 @@ async function runWithRetry(operation, options, shouldRetry, onSchedule, signal)
117
117
  var DEFAULT_TTC_ENDPOINT = "https://api.thetokencompany.com/v1/compress";
118
118
  var DEFAULT_TTC_MODEL = "bear-2";
119
119
  var DEFAULT_TTC_AGGRESSIVENESS = 0.2;
120
+ var DEFAULT_USAGETAP_COMPRESSION_ENDPOINT = "https://compress.usagetap.com/v1/compress";
121
+ var DEFAULT_USAGETAP_MESSAGES_COMPRESSION_ENDPOINT = "https://compress.usagetap.com/v1/messages/compress";
120
122
  var PROTECTED_TEXT_PATTERN = /<ttc_safe>[\s\S]*?<\/ttc_safe>|<usagetap_safe>[\s\S]*?<\/usagetap_safe>/g;
121
123
  function protectPromptText(text) {
122
124
  return `<ttc_safe>${text}</ttc_safe>`;
123
125
  }
124
126
  var protect = protectPromptText;
125
127
  async function compressPrompt(options) {
128
+ const input = resolvePromptCompressionInput(options);
126
129
  try {
130
+ if (options.provider === "usagetap") {
131
+ return await compressWithUsageTap(options);
132
+ }
127
133
  if (options.provider === "thetokencompany" || options.tokenCompanyApiKey) {
128
134
  return await compressWithTheTokenCompany(options);
129
135
  }
130
136
  if (options.provider === "toon") {
131
- return compressPromptToon(options.input);
137
+ return compressPromptToon(input);
132
138
  }
133
- return compressPromptHeuristic(options.input);
139
+ return compressPromptHeuristic(input);
134
140
  } catch (error) {
135
141
  if (options.failOpen === false) {
136
142
  throw error;
137
143
  }
138
144
  return createPromptCompressionFallback(
139
- options.input,
145
+ input,
140
146
  options.provider ?? (options.tokenCompanyApiKey ? "thetokencompany" : "heuristic"),
141
147
  error
142
148
  );
@@ -170,6 +176,20 @@ function compressPromptToon(input) {
170
176
  "json-minify"
171
177
  ]);
172
178
  }
179
+ async function compressPromptMessages(options) {
180
+ try {
181
+ return await compressMessagesWithUsageTap(options);
182
+ } catch (error) {
183
+ if (options.failOpen === false) {
184
+ throw error;
185
+ }
186
+ return createPromptCompressionFallback(
187
+ options.input,
188
+ options.provider ?? "usagetap",
189
+ error
190
+ );
191
+ }
192
+ }
173
193
  async function compressWithTheTokenCompany(options) {
174
194
  if (!options.tokenCompanyApiKey) {
175
195
  throw new Error(
@@ -182,41 +202,131 @@ async function compressWithTheTokenCompany(options) {
182
202
  "A fetch implementation is required for The Token Company compression"
183
203
  );
184
204
  }
205
+ return compressWithCompatibleRemoteProvider({
206
+ options,
207
+ provider: "thetokencompany",
208
+ endpoint: options.tokenCompanyEndpoint ?? DEFAULT_TTC_ENDPOINT,
209
+ model: options.model ?? options.tokenCompanyModel ?? DEFAULT_TTC_MODEL,
210
+ aggressiveness: options.aggressiveness ?? options.tokenCompanyAggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS,
211
+ apiKey: options.tokenCompanyApiKey,
212
+ appId: options.tokenCompanyAppId,
213
+ providerLabel: "The Token Company"
214
+ });
215
+ }
216
+ async function compressWithUsageTap(options) {
217
+ const fetchCandidate = options.fetchImpl ?? globalThis.fetch;
218
+ if (typeof fetchCandidate !== "function") {
219
+ throw new Error(
220
+ "A fetch implementation is required for UsageTap prompt compression"
221
+ );
222
+ }
223
+ return compressWithCompatibleRemoteProvider({
224
+ options,
225
+ provider: "usagetap",
226
+ endpoint: options.usageTapCompressionEndpoint ?? DEFAULT_USAGETAP_COMPRESSION_ENDPOINT,
227
+ model: options.model ?? options.usageTapCompressionModel ?? options.tokenCompanyModel ?? DEFAULT_TTC_MODEL,
228
+ aggressiveness: options.aggressiveness ?? options.usageTapCompressionAggressiveness ?? options.tokenCompanyAggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS,
229
+ apiKey: options.usageTapCompressionApiKey,
230
+ appId: options.tokenCompanyAppId,
231
+ providerLabel: "UsageTap prompt compression"
232
+ });
233
+ }
234
+ async function compressMessagesWithUsageTap(options) {
235
+ const fetchCandidate = options.fetchImpl ?? globalThis.fetch;
236
+ if (typeof fetchCandidate !== "function") {
237
+ throw new Error(
238
+ "A fetch implementation is required for UsageTap prompt message compression"
239
+ );
240
+ }
241
+ const aggressiveness = options.aggressiveness ?? options.usageTapCompressionAggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS;
242
+ validateAggressiveness(
243
+ aggressiveness,
244
+ "UsageTap prompt message compression"
245
+ );
185
246
  const original = stableStringifyInput(options.input);
186
- const heuristic = compressPromptHeuristic(options.input);
247
+ const headers = {
248
+ "content-type": "application/json"
249
+ };
250
+ if (options.usageTapCompressionApiKey) {
251
+ headers.authorization = `Bearer ${options.usageTapCompressionApiKey}`;
252
+ }
253
+ const response = await fetchCandidate(
254
+ options.usageTapCompressionMessagesEndpoint ?? DEFAULT_USAGETAP_MESSAGES_COMPRESSION_ENDPOINT,
255
+ {
256
+ method: "POST",
257
+ headers,
258
+ body: JSON.stringify({
259
+ ...cloneInputRecord(options.input),
260
+ compression_settings: { aggressiveness }
261
+ }),
262
+ signal: options.signal
263
+ }
264
+ );
265
+ if (!response.ok) {
266
+ throw new Error(
267
+ `UsageTap prompt message compression failed with HTTP ${response.status}`
268
+ );
269
+ }
270
+ const payload = await response.json();
271
+ const compressedInput = payload.compressed_request ?? payload.compressedInput ?? payload.compressed ?? (payload.messages !== void 0 ? { ...cloneInputRecord(options.input), messages: payload.messages } : void 0);
272
+ if (compressedInput === void 0) {
273
+ throw new Error(
274
+ "UsageTap prompt message compression response did not include compressed content"
275
+ );
276
+ }
277
+ const compressed = stableStringifyInput(compressedInput);
278
+ const tokenCounts = normalizeCompatibleTokenCounts(payload);
279
+ return buildResult(
280
+ options.input,
281
+ compressedInput,
282
+ "usagetap",
283
+ original,
284
+ compressed,
285
+ ["usagetap", "messages-endpoint"],
286
+ tokenCounts
287
+ );
288
+ }
289
+ async function compressWithCompatibleRemoteProvider(args) {
290
+ const { options, provider, endpoint, model, aggressiveness, apiKey, appId, providerLabel } = args;
291
+ const fetchCandidate = options.fetchImpl ?? globalThis.fetch;
292
+ const sourceInput = resolvePromptCompressionInput(options);
293
+ const original = stableStringifyInput(sourceInput);
294
+ const heuristic = compressPromptHeuristic(sourceInput);
187
295
  const input = typeof heuristic.compressedInput === "string" ? heuristic.compressedInput : stableStringifyInput(heuristic.compressedInput);
188
- const model = options.tokenCompanyModel ?? DEFAULT_TTC_MODEL;
189
- const aggressiveness = options.tokenCompanyAggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS;
190
- if (typeof aggressiveness !== "number" || !Number.isFinite(aggressiveness) || aggressiveness < 0 || aggressiveness > 1) {
191
- throw new Error("tokenCompanyAggressiveness must be between 0.0 and 1.0");
296
+ if (!isValidAggressiveness(aggressiveness)) {
297
+ throw new Error(`${providerLabel} aggressiveness must be between 0.0 and 1.0`);
298
+ }
299
+ const headers = {
300
+ "content-type": "application/json"
301
+ };
302
+ if (apiKey) {
303
+ headers.authorization = `Bearer ${apiKey}`;
192
304
  }
193
305
  const response = await fetchCandidate(
194
- options.tokenCompanyEndpoint ?? DEFAULT_TTC_ENDPOINT,
306
+ endpoint,
195
307
  {
196
308
  method: "POST",
197
- headers: {
198
- authorization: `Bearer ${options.tokenCompanyApiKey}`,
199
- "content-type": "application/json"
200
- },
309
+ headers,
201
310
  body: JSON.stringify({
202
311
  model,
203
312
  input,
313
+ ...provider === "usagetap" ? { text: input } : {},
204
314
  compression_settings: { aggressiveness },
205
- ...options.tokenCompanyAppId ? { app_id: options.tokenCompanyAppId } : {}
315
+ ...appId ? { app_id: appId } : {}
206
316
  }),
207
317
  signal: options.signal
208
318
  }
209
319
  );
210
320
  if (!response.ok) {
211
321
  throw new Error(
212
- `The Token Company compression failed with HTTP ${response.status}`
322
+ `${providerLabel} failed with HTTP ${response.status}`
213
323
  );
214
324
  }
215
325
  const payload = await response.json();
216
326
  const tokenCompanyResult = normalizeTheTokenCompanyCompressResponse(payload);
217
327
  const compressedInput = payload.compressedInput ?? payload.compressed ?? tokenCompanyResult?.output ?? payload.output ?? payload.text;
218
328
  if (compressedInput === void 0) {
219
- throw new Error("The Token Company response did not include compressed content");
329
+ throw new Error(`${providerLabel} response did not include compressed content`);
220
330
  }
221
331
  const compressed = stableStringifyInput(compressedInput);
222
332
  const tokenCounts = tokenCompanyResult ? {
@@ -225,15 +335,55 @@ async function compressWithTheTokenCompany(options) {
225
335
  savedTokens: tokenCompanyResult.tokens_saved
226
336
  } : void 0;
227
337
  return buildResult(
228
- options.input,
338
+ sourceInput,
229
339
  compressedInput,
230
- "thetokencompany",
340
+ provider,
231
341
  original,
232
342
  compressed,
233
- [...heuristic.techniques, "thetokencompany"],
343
+ [...heuristic.techniques, provider],
234
344
  tokenCounts
235
345
  );
236
346
  }
347
+ function resolvePromptCompressionInput(options) {
348
+ if (options.input !== void 0) {
349
+ return options.input;
350
+ }
351
+ if (options.text !== void 0) {
352
+ return options.text;
353
+ }
354
+ throw new Error("Prompt compression requires input or text");
355
+ }
356
+ function validateAggressiveness(value, label) {
357
+ if (typeof value === "number") {
358
+ if (!isValidAggressiveness(value)) {
359
+ throw new Error(`${label} aggressiveness must be between 0.0 and 1.0`);
360
+ }
361
+ return;
362
+ }
363
+ for (const aggressiveness of Object.values(value)) {
364
+ if (aggressiveness !== void 0 && !isValidAggressiveness(aggressiveness)) {
365
+ throw new Error(`${label} aggressiveness must be between 0.0 and 1.0`);
366
+ }
367
+ }
368
+ }
369
+ function isValidAggressiveness(value) {
370
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
371
+ }
372
+ function cloneInputRecord(input) {
373
+ return input && typeof input === "object" && !Array.isArray(input) ? { ...input } : { input };
374
+ }
375
+ function normalizeCompatibleTokenCounts(data) {
376
+ const inputTokens = typeof data.input_tokens === "number" ? data.input_tokens : data.original_input_tokens;
377
+ const outputTokens = data.output_tokens;
378
+ if (typeof inputTokens !== "number" || typeof outputTokens !== "number") {
379
+ return void 0;
380
+ }
381
+ return {
382
+ originalTokens: inputTokens,
383
+ compressedTokens: outputTokens,
384
+ savedTokens: typeof data.tokens_saved === "number" ? data.tokens_saved : inputTokens - outputTokens
385
+ };
386
+ }
237
387
  function normalizeTheTokenCompanyCompressResponse(data) {
238
388
  if (typeof data.output !== "string" || typeof data.output_tokens !== "number") {
239
389
  return void 0;
@@ -618,7 +768,8 @@ var IDEMPOTENCY_HEADER = "idempotency-key";
618
768
  var SDK_HEADER = "x-usage-sdk";
619
769
  var USER_AGENT = "UsageTapClient";
620
770
  var CANONICAL_MEDIA_TYPE = "application/vnd.usagetap.v1+json";
621
- var SDK_VERSION = "1.1.0" ;
771
+ var DEFAULT_BASE_URL = "https://api.usagetap.com";
772
+ var SDK_VERSION = "1.3.1" ;
622
773
  var HAS_WINDOW = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
623
774
  var UsageTapClient = class {
624
775
  apiKey;
@@ -635,26 +786,23 @@ var UsageTapClient = class {
635
786
  autoIdempotency;
636
787
  tokenCompanyApiKey;
637
788
  tokenCompanyEndpoint;
789
+ model;
638
790
  tokenCompanyModel;
791
+ aggressiveness;
639
792
  tokenCompanyAggressiveness;
640
793
  tokenCompanyAppId;
641
- constructor(options) {
642
- if (!options) {
643
- throw new UsageTapError(
644
- "USAGETAP_BAD_REQUEST",
645
- "UsageTapClient options are required"
646
- );
647
- }
648
- if (!options.apiKey) {
649
- throw new UsageTapError(
650
- "USAGETAP_BAD_REQUEST",
651
- "UsageTapClient requires an apiKey"
652
- );
653
- }
654
- if (!options.baseUrl) {
794
+ usageTapCompressionApiKey;
795
+ usageTapCompressionEndpoint;
796
+ usageTapCompressionMessagesEndpoint;
797
+ usageTapCompressionModel;
798
+ usageTapCompressionAggressiveness;
799
+ constructor(options = {}) {
800
+ const apiKey = options.apiKey?.trim() || readEnvironmentVariable("USAGETAP_API_KEY");
801
+ const baseUrl = options.baseUrl?.trim() || readEnvironmentVariable("USAGETAP_BASE_URL") || DEFAULT_BASE_URL;
802
+ if (!apiKey) {
655
803
  throw new UsageTapError(
656
804
  "USAGETAP_BAD_REQUEST",
657
- "UsageTapClient requires a baseUrl"
805
+ "UsageTapClient requires an apiKey or the USAGETAP_API_KEY environment variable"
658
806
  );
659
807
  }
660
808
  if (HAS_WINDOW && !options.allowBrowser) {
@@ -670,9 +818,9 @@ var UsageTapClient = class {
670
818
  "A global fetch implementation was not found. Pass fetchImpl in UsageTapClientOptions."
671
819
  );
672
820
  }
673
- const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);
821
+ const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
674
822
  this.baseUrl = new URL(normalizedBaseUrl);
675
- this.apiKey = options.apiKey;
823
+ this.apiKey = apiKey;
676
824
  this.fetchImpl = wrapFetchImplementation(fetchCandidate, !options.fetchImpl);
677
825
  this.defaultFeature = options.defaultFeature;
678
826
  this.defaultTags = options.defaultTags?.length ? dedupeStrings(options.defaultTags) : void 0;
@@ -685,9 +833,16 @@ var UsageTapClient = class {
685
833
  this.autoIdempotency = options.autoIdempotency ?? true;
686
834
  this.tokenCompanyApiKey = options.tokenCompanyApiKey;
687
835
  this.tokenCompanyEndpoint = options.tokenCompanyEndpoint;
836
+ this.model = options.model;
688
837
  this.tokenCompanyModel = options.tokenCompanyModel;
838
+ this.aggressiveness = options.aggressiveness;
689
839
  this.tokenCompanyAggressiveness = options.tokenCompanyAggressiveness;
690
840
  this.tokenCompanyAppId = options.tokenCompanyAppId;
841
+ this.usageTapCompressionApiKey = options.usageTapCompressionApiKey ?? apiKey;
842
+ this.usageTapCompressionEndpoint = options.usageTapCompressionEndpoint;
843
+ this.usageTapCompressionMessagesEndpoint = options.usageTapCompressionMessagesEndpoint;
844
+ this.usageTapCompressionModel = options.usageTapCompressionModel;
845
+ this.usageTapCompressionAggressiveness = options.usageTapCompressionAggressiveness;
691
846
  }
692
847
  async beginCall(request, options = {}) {
693
848
  const idempotencyKey = request.idempotencyKey ?? request.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
@@ -717,11 +872,22 @@ var UsageTapClient = class {
717
872
  "promptCompress requires callId"
718
873
  );
719
874
  }
720
- const result = await this.compressPromptInput(request.input, {
875
+ const requestInput = request.input ?? request.text;
876
+ if (requestInput === void 0) {
877
+ throw new UsageTapError(
878
+ "USAGETAP_BAD_REQUEST",
879
+ "promptCompress requires input or text"
880
+ );
881
+ }
882
+ const result = await this.compressPromptInput(requestInput, {
721
883
  provider: request.provider,
884
+ model: request.model,
722
885
  tokenCompanyModel: request.tokenCompanyModel,
886
+ aggressiveness: request.aggressiveness,
723
887
  tokenCompanyAggressiveness: request.tokenCompanyAggressiveness,
724
888
  tokenCompanyAppId: request.tokenCompanyAppId,
889
+ usageTapCompressionModel: request.usageTapCompressionModel,
890
+ usageTapCompressionAggressiveness: request.usageTapCompressionAggressiveness,
725
891
  signal: options.signal
726
892
  });
727
893
  try {
@@ -736,7 +902,7 @@ var UsageTapClient = class {
736
902
  } catch (error) {
737
903
  return {
738
904
  ...createPromptCompressionFallback(
739
- request.input,
905
+ requestInput,
740
906
  request.provider ?? result.provider,
741
907
  error
742
908
  ),
@@ -750,9 +916,52 @@ var UsageTapClient = class {
750
916
  provider: options.provider,
751
917
  tokenCompanyApiKey: this.tokenCompanyApiKey,
752
918
  tokenCompanyEndpoint: this.tokenCompanyEndpoint,
919
+ model: options.model ?? this.model,
753
920
  tokenCompanyModel: options.tokenCompanyModel ?? this.tokenCompanyModel,
921
+ aggressiveness: options.aggressiveness ?? this.aggressiveness,
754
922
  tokenCompanyAggressiveness: options.tokenCompanyAggressiveness ?? this.tokenCompanyAggressiveness,
755
923
  tokenCompanyAppId: options.tokenCompanyAppId ?? this.tokenCompanyAppId,
924
+ usageTapCompressionApiKey: this.usageTapCompressionApiKey,
925
+ usageTapCompressionEndpoint: this.usageTapCompressionEndpoint,
926
+ usageTapCompressionModel: options.usageTapCompressionModel ?? this.usageTapCompressionModel,
927
+ usageTapCompressionAggressiveness: options.usageTapCompressionAggressiveness ?? this.usageTapCompressionAggressiveness,
928
+ fetchImpl: this.fetchImpl,
929
+ signal: options.signal,
930
+ failOpen: options.failOpen
931
+ });
932
+ }
933
+ /**
934
+ * Compress text with UsageTap's hosted compression service.
935
+ *
936
+ * This is the short, standalone path. It does not create a metered call and
937
+ * fails open to the original text unless failOpen is explicitly disabled.
938
+ */
939
+ async compress(text, options = {}) {
940
+ if (typeof text !== "string") {
941
+ throw new UsageTapError(
942
+ "USAGETAP_BAD_REQUEST",
943
+ "compress requires text"
944
+ );
945
+ }
946
+ const result = await this.compressPromptInput(text, {
947
+ ...options,
948
+ provider: "usagetap"
949
+ });
950
+ const output = typeof result.compressedInput === "string" ? result.compressedInput : text;
951
+ return {
952
+ ...result,
953
+ compressedInput: output,
954
+ output
955
+ };
956
+ }
957
+ async compressPromptMessages(input, options = {}) {
958
+ return compressPromptMessages({
959
+ input,
960
+ provider: options.provider ?? "usagetap",
961
+ usageTapCompressionApiKey: this.usageTapCompressionApiKey,
962
+ usageTapCompressionMessagesEndpoint: this.usageTapCompressionMessagesEndpoint,
963
+ aggressiveness: options.aggressiveness ?? this.aggressiveness,
964
+ usageTapCompressionAggressiveness: options.usageTapCompressionAggressiveness ?? this.usageTapCompressionAggressiveness,
756
965
  fetchImpl: this.fetchImpl,
757
966
  signal: options.signal,
758
967
  failOpen: options.failOpen
@@ -998,6 +1207,14 @@ var UsageTapClient = class {
998
1207
  }
999
1208
  return handlerResult;
1000
1209
  }
1210
+ /**
1211
+ * Meter one operation. Pass only a customer ID for the common path, or the
1212
+ * existing begin-call request object when feature, tags, or entitlements are needed.
1213
+ */
1214
+ async meter(request, handler, options = {}) {
1215
+ const beginRequest = typeof request === "string" ? { customerId: request } : request;
1216
+ return this.withUsage(beginRequest, handler, options);
1217
+ }
1001
1218
  toPromptCompressionTelemetry(result) {
1002
1219
  return {
1003
1220
  provider: result.provider,
@@ -1310,6 +1527,11 @@ function sanitizeDetails(payload) {
1310
1527
  if (payload.error) details.error = payload.error;
1311
1528
  return Object.keys(details).length ? details : void 0;
1312
1529
  }
1530
+ function readEnvironmentVariable(name) {
1531
+ const runtime = globalThis;
1532
+ const value = runtime.process?.env?.[name]?.trim();
1533
+ return value || void 0;
1534
+ }
1313
1535
  function normalizeBaseUrl(baseUrl) {
1314
1536
  const trimmed = baseUrl.trim();
1315
1537
  if (!trimmed) return trimmed;
@@ -1599,6 +1821,6 @@ async function finalizeCall(callState, usageTap, error, usage) {
1599
1821
  }
1600
1822
  }
1601
1823
 
1602
- export { UsageTapClient, UsageTapError, compressPrompt, compressPromptHeuristic, compressPromptToon, createIdempotencyKey, estimatePromptTokens, isUsageTapError, protect, protectPromptText, wrapFetch };
1824
+ export { UsageTapClient as UsageTap, UsageTapClient, UsageTapError, compressPrompt, compressPromptHeuristic, compressPromptMessages, compressPromptToon, createIdempotencyKey, estimatePromptTokens, isUsageTapError, protect, protectPromptText, wrapFetch };
1603
1825
  //# sourceMappingURL=index.mjs.map
1604
1826
  //# sourceMappingURL=index.mjs.map