@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.cjs CHANGED
@@ -119,26 +119,32 @@ async function runWithRetry(operation, options, shouldRetry, onSchedule, signal)
119
119
  var DEFAULT_TTC_ENDPOINT = "https://api.thetokencompany.com/v1/compress";
120
120
  var DEFAULT_TTC_MODEL = "bear-2";
121
121
  var DEFAULT_TTC_AGGRESSIVENESS = 0.2;
122
+ var DEFAULT_USAGETAP_COMPRESSION_ENDPOINT = "https://compress.usagetap.com/v1/compress";
123
+ var DEFAULT_USAGETAP_MESSAGES_COMPRESSION_ENDPOINT = "https://compress.usagetap.com/v1/messages/compress";
122
124
  var PROTECTED_TEXT_PATTERN = /<ttc_safe>[\s\S]*?<\/ttc_safe>|<usagetap_safe>[\s\S]*?<\/usagetap_safe>/g;
123
125
  function protectPromptText(text) {
124
126
  return `<ttc_safe>${text}</ttc_safe>`;
125
127
  }
126
128
  var protect = protectPromptText;
127
129
  async function compressPrompt(options) {
130
+ const input = resolvePromptCompressionInput(options);
128
131
  try {
132
+ if (options.provider === "usagetap") {
133
+ return await compressWithUsageTap(options);
134
+ }
129
135
  if (options.provider === "thetokencompany" || options.tokenCompanyApiKey) {
130
136
  return await compressWithTheTokenCompany(options);
131
137
  }
132
138
  if (options.provider === "toon") {
133
- return compressPromptToon(options.input);
139
+ return compressPromptToon(input);
134
140
  }
135
- return compressPromptHeuristic(options.input);
141
+ return compressPromptHeuristic(input);
136
142
  } catch (error) {
137
143
  if (options.failOpen === false) {
138
144
  throw error;
139
145
  }
140
146
  return createPromptCompressionFallback(
141
- options.input,
147
+ input,
142
148
  options.provider ?? (options.tokenCompanyApiKey ? "thetokencompany" : "heuristic"),
143
149
  error
144
150
  );
@@ -172,6 +178,20 @@ function compressPromptToon(input) {
172
178
  "json-minify"
173
179
  ]);
174
180
  }
181
+ async function compressPromptMessages(options) {
182
+ try {
183
+ return await compressMessagesWithUsageTap(options);
184
+ } catch (error) {
185
+ if (options.failOpen === false) {
186
+ throw error;
187
+ }
188
+ return createPromptCompressionFallback(
189
+ options.input,
190
+ options.provider ?? "usagetap",
191
+ error
192
+ );
193
+ }
194
+ }
175
195
  async function compressWithTheTokenCompany(options) {
176
196
  if (!options.tokenCompanyApiKey) {
177
197
  throw new Error(
@@ -184,41 +204,131 @@ async function compressWithTheTokenCompany(options) {
184
204
  "A fetch implementation is required for The Token Company compression"
185
205
  );
186
206
  }
207
+ return compressWithCompatibleRemoteProvider({
208
+ options,
209
+ provider: "thetokencompany",
210
+ endpoint: options.tokenCompanyEndpoint ?? DEFAULT_TTC_ENDPOINT,
211
+ model: options.model ?? options.tokenCompanyModel ?? DEFAULT_TTC_MODEL,
212
+ aggressiveness: options.aggressiveness ?? options.tokenCompanyAggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS,
213
+ apiKey: options.tokenCompanyApiKey,
214
+ appId: options.tokenCompanyAppId,
215
+ providerLabel: "The Token Company"
216
+ });
217
+ }
218
+ async function compressWithUsageTap(options) {
219
+ const fetchCandidate = options.fetchImpl ?? globalThis.fetch;
220
+ if (typeof fetchCandidate !== "function") {
221
+ throw new Error(
222
+ "A fetch implementation is required for UsageTap prompt compression"
223
+ );
224
+ }
225
+ return compressWithCompatibleRemoteProvider({
226
+ options,
227
+ provider: "usagetap",
228
+ endpoint: options.usageTapCompressionEndpoint ?? DEFAULT_USAGETAP_COMPRESSION_ENDPOINT,
229
+ model: options.model ?? options.usageTapCompressionModel ?? options.tokenCompanyModel ?? DEFAULT_TTC_MODEL,
230
+ aggressiveness: options.aggressiveness ?? options.usageTapCompressionAggressiveness ?? options.tokenCompanyAggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS,
231
+ apiKey: options.usageTapCompressionApiKey,
232
+ appId: options.tokenCompanyAppId,
233
+ providerLabel: "UsageTap prompt compression"
234
+ });
235
+ }
236
+ async function compressMessagesWithUsageTap(options) {
237
+ const fetchCandidate = options.fetchImpl ?? globalThis.fetch;
238
+ if (typeof fetchCandidate !== "function") {
239
+ throw new Error(
240
+ "A fetch implementation is required for UsageTap prompt message compression"
241
+ );
242
+ }
243
+ const aggressiveness = options.aggressiveness ?? options.usageTapCompressionAggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS;
244
+ validateAggressiveness(
245
+ aggressiveness,
246
+ "UsageTap prompt message compression"
247
+ );
187
248
  const original = stableStringifyInput(options.input);
188
- const heuristic = compressPromptHeuristic(options.input);
249
+ const headers = {
250
+ "content-type": "application/json"
251
+ };
252
+ if (options.usageTapCompressionApiKey) {
253
+ headers.authorization = `Bearer ${options.usageTapCompressionApiKey}`;
254
+ }
255
+ const response = await fetchCandidate(
256
+ options.usageTapCompressionMessagesEndpoint ?? DEFAULT_USAGETAP_MESSAGES_COMPRESSION_ENDPOINT,
257
+ {
258
+ method: "POST",
259
+ headers,
260
+ body: JSON.stringify({
261
+ ...cloneInputRecord(options.input),
262
+ compression_settings: { aggressiveness }
263
+ }),
264
+ signal: options.signal
265
+ }
266
+ );
267
+ if (!response.ok) {
268
+ throw new Error(
269
+ `UsageTap prompt message compression failed with HTTP ${response.status}`
270
+ );
271
+ }
272
+ const payload = await response.json();
273
+ const compressedInput = payload.compressed_request ?? payload.compressedInput ?? payload.compressed ?? (payload.messages !== void 0 ? { ...cloneInputRecord(options.input), messages: payload.messages } : void 0);
274
+ if (compressedInput === void 0) {
275
+ throw new Error(
276
+ "UsageTap prompt message compression response did not include compressed content"
277
+ );
278
+ }
279
+ const compressed = stableStringifyInput(compressedInput);
280
+ const tokenCounts = normalizeCompatibleTokenCounts(payload);
281
+ return buildResult(
282
+ options.input,
283
+ compressedInput,
284
+ "usagetap",
285
+ original,
286
+ compressed,
287
+ ["usagetap", "messages-endpoint"],
288
+ tokenCounts
289
+ );
290
+ }
291
+ async function compressWithCompatibleRemoteProvider(args) {
292
+ const { options, provider, endpoint, model, aggressiveness, apiKey, appId, providerLabel } = args;
293
+ const fetchCandidate = options.fetchImpl ?? globalThis.fetch;
294
+ const sourceInput = resolvePromptCompressionInput(options);
295
+ const original = stableStringifyInput(sourceInput);
296
+ const heuristic = compressPromptHeuristic(sourceInput);
189
297
  const input = typeof heuristic.compressedInput === "string" ? heuristic.compressedInput : stableStringifyInput(heuristic.compressedInput);
190
- const model = options.tokenCompanyModel ?? DEFAULT_TTC_MODEL;
191
- const aggressiveness = options.tokenCompanyAggressiveness ?? DEFAULT_TTC_AGGRESSIVENESS;
192
- if (typeof aggressiveness !== "number" || !Number.isFinite(aggressiveness) || aggressiveness < 0 || aggressiveness > 1) {
193
- throw new Error("tokenCompanyAggressiveness must be between 0.0 and 1.0");
298
+ if (!isValidAggressiveness(aggressiveness)) {
299
+ throw new Error(`${providerLabel} aggressiveness must be between 0.0 and 1.0`);
300
+ }
301
+ const headers = {
302
+ "content-type": "application/json"
303
+ };
304
+ if (apiKey) {
305
+ headers.authorization = `Bearer ${apiKey}`;
194
306
  }
195
307
  const response = await fetchCandidate(
196
- options.tokenCompanyEndpoint ?? DEFAULT_TTC_ENDPOINT,
308
+ endpoint,
197
309
  {
198
310
  method: "POST",
199
- headers: {
200
- authorization: `Bearer ${options.tokenCompanyApiKey}`,
201
- "content-type": "application/json"
202
- },
311
+ headers,
203
312
  body: JSON.stringify({
204
313
  model,
205
314
  input,
315
+ ...provider === "usagetap" ? { text: input } : {},
206
316
  compression_settings: { aggressiveness },
207
- ...options.tokenCompanyAppId ? { app_id: options.tokenCompanyAppId } : {}
317
+ ...appId ? { app_id: appId } : {}
208
318
  }),
209
319
  signal: options.signal
210
320
  }
211
321
  );
212
322
  if (!response.ok) {
213
323
  throw new Error(
214
- `The Token Company compression failed with HTTP ${response.status}`
324
+ `${providerLabel} failed with HTTP ${response.status}`
215
325
  );
216
326
  }
217
327
  const payload = await response.json();
218
328
  const tokenCompanyResult = normalizeTheTokenCompanyCompressResponse(payload);
219
329
  const compressedInput = payload.compressedInput ?? payload.compressed ?? tokenCompanyResult?.output ?? payload.output ?? payload.text;
220
330
  if (compressedInput === void 0) {
221
- throw new Error("The Token Company response did not include compressed content");
331
+ throw new Error(`${providerLabel} response did not include compressed content`);
222
332
  }
223
333
  const compressed = stableStringifyInput(compressedInput);
224
334
  const tokenCounts = tokenCompanyResult ? {
@@ -227,15 +337,55 @@ async function compressWithTheTokenCompany(options) {
227
337
  savedTokens: tokenCompanyResult.tokens_saved
228
338
  } : void 0;
229
339
  return buildResult(
230
- options.input,
340
+ sourceInput,
231
341
  compressedInput,
232
- "thetokencompany",
342
+ provider,
233
343
  original,
234
344
  compressed,
235
- [...heuristic.techniques, "thetokencompany"],
345
+ [...heuristic.techniques, provider],
236
346
  tokenCounts
237
347
  );
238
348
  }
349
+ function resolvePromptCompressionInput(options) {
350
+ if (options.input !== void 0) {
351
+ return options.input;
352
+ }
353
+ if (options.text !== void 0) {
354
+ return options.text;
355
+ }
356
+ throw new Error("Prompt compression requires input or text");
357
+ }
358
+ function validateAggressiveness(value, label) {
359
+ if (typeof value === "number") {
360
+ if (!isValidAggressiveness(value)) {
361
+ throw new Error(`${label} aggressiveness must be between 0.0 and 1.0`);
362
+ }
363
+ return;
364
+ }
365
+ for (const aggressiveness of Object.values(value)) {
366
+ if (aggressiveness !== void 0 && !isValidAggressiveness(aggressiveness)) {
367
+ throw new Error(`${label} aggressiveness must be between 0.0 and 1.0`);
368
+ }
369
+ }
370
+ }
371
+ function isValidAggressiveness(value) {
372
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
373
+ }
374
+ function cloneInputRecord(input) {
375
+ return input && typeof input === "object" && !Array.isArray(input) ? { ...input } : { input };
376
+ }
377
+ function normalizeCompatibleTokenCounts(data) {
378
+ const inputTokens = typeof data.input_tokens === "number" ? data.input_tokens : data.original_input_tokens;
379
+ const outputTokens = data.output_tokens;
380
+ if (typeof inputTokens !== "number" || typeof outputTokens !== "number") {
381
+ return void 0;
382
+ }
383
+ return {
384
+ originalTokens: inputTokens,
385
+ compressedTokens: outputTokens,
386
+ savedTokens: typeof data.tokens_saved === "number" ? data.tokens_saved : inputTokens - outputTokens
387
+ };
388
+ }
239
389
  function normalizeTheTokenCompanyCompressResponse(data) {
240
390
  if (typeof data.output !== "string" || typeof data.output_tokens !== "number") {
241
391
  return void 0;
@@ -620,7 +770,8 @@ var IDEMPOTENCY_HEADER = "idempotency-key";
620
770
  var SDK_HEADER = "x-usage-sdk";
621
771
  var USER_AGENT = "UsageTapClient";
622
772
  var CANONICAL_MEDIA_TYPE = "application/vnd.usagetap.v1+json";
623
- var SDK_VERSION = "1.1.0" ;
773
+ var DEFAULT_BASE_URL = "https://api.usagetap.com";
774
+ var SDK_VERSION = "1.3.1" ;
624
775
  var HAS_WINDOW = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
625
776
  var UsageTapClient = class {
626
777
  apiKey;
@@ -637,26 +788,23 @@ var UsageTapClient = class {
637
788
  autoIdempotency;
638
789
  tokenCompanyApiKey;
639
790
  tokenCompanyEndpoint;
791
+ model;
640
792
  tokenCompanyModel;
793
+ aggressiveness;
641
794
  tokenCompanyAggressiveness;
642
795
  tokenCompanyAppId;
643
- constructor(options) {
644
- if (!options) {
645
- throw new UsageTapError(
646
- "USAGETAP_BAD_REQUEST",
647
- "UsageTapClient options are required"
648
- );
649
- }
650
- if (!options.apiKey) {
651
- throw new UsageTapError(
652
- "USAGETAP_BAD_REQUEST",
653
- "UsageTapClient requires an apiKey"
654
- );
655
- }
656
- if (!options.baseUrl) {
796
+ usageTapCompressionApiKey;
797
+ usageTapCompressionEndpoint;
798
+ usageTapCompressionMessagesEndpoint;
799
+ usageTapCompressionModel;
800
+ usageTapCompressionAggressiveness;
801
+ constructor(options = {}) {
802
+ const apiKey = options.apiKey?.trim() || readEnvironmentVariable("USAGETAP_API_KEY");
803
+ const baseUrl = options.baseUrl?.trim() || readEnvironmentVariable("USAGETAP_BASE_URL") || DEFAULT_BASE_URL;
804
+ if (!apiKey) {
657
805
  throw new UsageTapError(
658
806
  "USAGETAP_BAD_REQUEST",
659
- "UsageTapClient requires a baseUrl"
807
+ "UsageTapClient requires an apiKey or the USAGETAP_API_KEY environment variable"
660
808
  );
661
809
  }
662
810
  if (HAS_WINDOW && !options.allowBrowser) {
@@ -672,9 +820,9 @@ var UsageTapClient = class {
672
820
  "A global fetch implementation was not found. Pass fetchImpl in UsageTapClientOptions."
673
821
  );
674
822
  }
675
- const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);
823
+ const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
676
824
  this.baseUrl = new URL(normalizedBaseUrl);
677
- this.apiKey = options.apiKey;
825
+ this.apiKey = apiKey;
678
826
  this.fetchImpl = wrapFetchImplementation(fetchCandidate, !options.fetchImpl);
679
827
  this.defaultFeature = options.defaultFeature;
680
828
  this.defaultTags = options.defaultTags?.length ? dedupeStrings(options.defaultTags) : void 0;
@@ -687,9 +835,16 @@ var UsageTapClient = class {
687
835
  this.autoIdempotency = options.autoIdempotency ?? true;
688
836
  this.tokenCompanyApiKey = options.tokenCompanyApiKey;
689
837
  this.tokenCompanyEndpoint = options.tokenCompanyEndpoint;
838
+ this.model = options.model;
690
839
  this.tokenCompanyModel = options.tokenCompanyModel;
840
+ this.aggressiveness = options.aggressiveness;
691
841
  this.tokenCompanyAggressiveness = options.tokenCompanyAggressiveness;
692
842
  this.tokenCompanyAppId = options.tokenCompanyAppId;
843
+ this.usageTapCompressionApiKey = options.usageTapCompressionApiKey ?? apiKey;
844
+ this.usageTapCompressionEndpoint = options.usageTapCompressionEndpoint;
845
+ this.usageTapCompressionMessagesEndpoint = options.usageTapCompressionMessagesEndpoint;
846
+ this.usageTapCompressionModel = options.usageTapCompressionModel;
847
+ this.usageTapCompressionAggressiveness = options.usageTapCompressionAggressiveness;
693
848
  }
694
849
  async beginCall(request, options = {}) {
695
850
  const idempotencyKey = request.idempotencyKey ?? request.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
@@ -719,11 +874,22 @@ var UsageTapClient = class {
719
874
  "promptCompress requires callId"
720
875
  );
721
876
  }
722
- const result = await this.compressPromptInput(request.input, {
877
+ const requestInput = request.input ?? request.text;
878
+ if (requestInput === void 0) {
879
+ throw new UsageTapError(
880
+ "USAGETAP_BAD_REQUEST",
881
+ "promptCompress requires input or text"
882
+ );
883
+ }
884
+ const result = await this.compressPromptInput(requestInput, {
723
885
  provider: request.provider,
886
+ model: request.model,
724
887
  tokenCompanyModel: request.tokenCompanyModel,
888
+ aggressiveness: request.aggressiveness,
725
889
  tokenCompanyAggressiveness: request.tokenCompanyAggressiveness,
726
890
  tokenCompanyAppId: request.tokenCompanyAppId,
891
+ usageTapCompressionModel: request.usageTapCompressionModel,
892
+ usageTapCompressionAggressiveness: request.usageTapCompressionAggressiveness,
727
893
  signal: options.signal
728
894
  });
729
895
  try {
@@ -738,7 +904,7 @@ var UsageTapClient = class {
738
904
  } catch (error) {
739
905
  return {
740
906
  ...createPromptCompressionFallback(
741
- request.input,
907
+ requestInput,
742
908
  request.provider ?? result.provider,
743
909
  error
744
910
  ),
@@ -752,9 +918,52 @@ var UsageTapClient = class {
752
918
  provider: options.provider,
753
919
  tokenCompanyApiKey: this.tokenCompanyApiKey,
754
920
  tokenCompanyEndpoint: this.tokenCompanyEndpoint,
921
+ model: options.model ?? this.model,
755
922
  tokenCompanyModel: options.tokenCompanyModel ?? this.tokenCompanyModel,
923
+ aggressiveness: options.aggressiveness ?? this.aggressiveness,
756
924
  tokenCompanyAggressiveness: options.tokenCompanyAggressiveness ?? this.tokenCompanyAggressiveness,
757
925
  tokenCompanyAppId: options.tokenCompanyAppId ?? this.tokenCompanyAppId,
926
+ usageTapCompressionApiKey: this.usageTapCompressionApiKey,
927
+ usageTapCompressionEndpoint: this.usageTapCompressionEndpoint,
928
+ usageTapCompressionModel: options.usageTapCompressionModel ?? this.usageTapCompressionModel,
929
+ usageTapCompressionAggressiveness: options.usageTapCompressionAggressiveness ?? this.usageTapCompressionAggressiveness,
930
+ fetchImpl: this.fetchImpl,
931
+ signal: options.signal,
932
+ failOpen: options.failOpen
933
+ });
934
+ }
935
+ /**
936
+ * Compress text with UsageTap's hosted compression service.
937
+ *
938
+ * This is the short, standalone path. It does not create a metered call and
939
+ * fails open to the original text unless failOpen is explicitly disabled.
940
+ */
941
+ async compress(text, options = {}) {
942
+ if (typeof text !== "string") {
943
+ throw new UsageTapError(
944
+ "USAGETAP_BAD_REQUEST",
945
+ "compress requires text"
946
+ );
947
+ }
948
+ const result = await this.compressPromptInput(text, {
949
+ ...options,
950
+ provider: "usagetap"
951
+ });
952
+ const output = typeof result.compressedInput === "string" ? result.compressedInput : text;
953
+ return {
954
+ ...result,
955
+ compressedInput: output,
956
+ output
957
+ };
958
+ }
959
+ async compressPromptMessages(input, options = {}) {
960
+ return compressPromptMessages({
961
+ input,
962
+ provider: options.provider ?? "usagetap",
963
+ usageTapCompressionApiKey: this.usageTapCompressionApiKey,
964
+ usageTapCompressionMessagesEndpoint: this.usageTapCompressionMessagesEndpoint,
965
+ aggressiveness: options.aggressiveness ?? this.aggressiveness,
966
+ usageTapCompressionAggressiveness: options.usageTapCompressionAggressiveness ?? this.usageTapCompressionAggressiveness,
758
967
  fetchImpl: this.fetchImpl,
759
968
  signal: options.signal,
760
969
  failOpen: options.failOpen
@@ -1000,6 +1209,14 @@ var UsageTapClient = class {
1000
1209
  }
1001
1210
  return handlerResult;
1002
1211
  }
1212
+ /**
1213
+ * Meter one operation. Pass only a customer ID for the common path, or the
1214
+ * existing begin-call request object when feature, tags, or entitlements are needed.
1215
+ */
1216
+ async meter(request, handler, options = {}) {
1217
+ const beginRequest = typeof request === "string" ? { customerId: request } : request;
1218
+ return this.withUsage(beginRequest, handler, options);
1219
+ }
1003
1220
  toPromptCompressionTelemetry(result) {
1004
1221
  return {
1005
1222
  provider: result.provider,
@@ -1312,6 +1529,11 @@ function sanitizeDetails(payload) {
1312
1529
  if (payload.error) details.error = payload.error;
1313
1530
  return Object.keys(details).length ? details : void 0;
1314
1531
  }
1532
+ function readEnvironmentVariable(name) {
1533
+ const runtime = globalThis;
1534
+ const value = runtime.process?.env?.[name]?.trim();
1535
+ return value || void 0;
1536
+ }
1315
1537
  function normalizeBaseUrl(baseUrl) {
1316
1538
  const trimmed = baseUrl.trim();
1317
1539
  if (!trimmed) return trimmed;
@@ -1601,10 +1823,12 @@ async function finalizeCall(callState, usageTap, error, usage) {
1601
1823
  }
1602
1824
  }
1603
1825
 
1826
+ exports.UsageTap = UsageTapClient;
1604
1827
  exports.UsageTapClient = UsageTapClient;
1605
1828
  exports.UsageTapError = UsageTapError;
1606
1829
  exports.compressPrompt = compressPrompt;
1607
1830
  exports.compressPromptHeuristic = compressPromptHeuristic;
1831
+ exports.compressPromptMessages = compressPromptMessages;
1608
1832
  exports.compressPromptToon = compressPromptToon;
1609
1833
  exports.createIdempotencyKey = createIdempotencyKey;
1610
1834
  exports.estimatePromptTokens = estimatePromptTokens;