@usagetap/sdk 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +25 -1
  2. package/dist/adapters/anthropic.cjs +67 -1
  3. package/dist/adapters/anthropic.cjs.map +1 -1
  4. package/dist/adapters/anthropic.d.cts +10 -1
  5. package/dist/adapters/anthropic.d.ts +10 -1
  6. package/dist/adapters/anthropic.mjs +67 -1
  7. package/dist/adapters/anthropic.mjs.map +1 -1
  8. package/dist/adapters/openai.cjs +67 -1
  9. package/dist/adapters/openai.cjs.map +1 -1
  10. package/dist/adapters/openai.d.cts +10 -1
  11. package/dist/adapters/openai.d.ts +10 -1
  12. package/dist/adapters/openai.mjs +67 -1
  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 +67 -1
  19. package/dist/anthropic/index.cjs.map +1 -1
  20. package/dist/anthropic/index.d.cts +1 -1
  21. package/dist/anthropic/index.d.ts +1 -1
  22. package/dist/anthropic/index.mjs +67 -1
  23. package/dist/anthropic/index.mjs.map +1 -1
  24. package/dist/{client-BA-QlnRq.d.cts → client-EMXt9_fA.d.cts} +77 -8
  25. package/dist/{client-BA-QlnRq.d.ts → client-EMXt9_fA.d.ts} +77 -8
  26. package/dist/express/index.cjs +67 -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 +67 -1
  31. package/dist/express/index.mjs.map +1 -1
  32. package/dist/index.cjs +217 -22
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +2 -2
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.mjs +217 -23
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/openai/index.cjs +67 -1
  39. package/dist/openai/index.cjs.map +1 -1
  40. package/dist/openai/index.d.cts +1 -1
  41. package/dist/openai/index.d.ts +1 -1
  42. package/dist/openai/index.mjs +67 -1
  43. package/dist/openai/index.mjs.map +1 -1
  44. package/package.json +1 -1
package/README.md CHANGED
@@ -178,7 +178,31 @@ await anthropic.messages.create({
178
178
  });
179
179
  ```
180
180
 
181
- When using The Token Company, configure `tokenCompanyApiKey` on `UsageTapClient` and set `provider: "thetokencompany"`. Optional `tokenCompanyModel`, `tokenCompanyAggressiveness`, and `tokenCompanyAppId` are supported at the client, manual `promptCompress`, and wrapper levels. Use `protectPromptText()` for text that must be passed through unchanged by compression-compatible providers.
181
+ Use `provider: "usagetap"` to compress with UsageTap's hosted endpoints. Manual `promptCompress()` and `compressPromptInput()` use the single-text The Token Company-compatible endpoint at `https://compress.usagetap.com/v1/compress`, where `aggressiveness` is a single number from `0.0` to `1.0`. `wrapOpenAI()` and `wrapAnthropic()` use the message/request endpoint at `https://compress.usagetap.com/v1/messages/compress`, where `aggressiveness` may be a per-role object:
182
+
183
+ ```ts
184
+ const result = await usageTap.promptCompress({
185
+ callId: begin.data.callId,
186
+ text: "Your text here",
187
+ provider: "usagetap",
188
+ model: "bear-2",
189
+ aggressiveness: 0.5,
190
+ });
191
+ ```
192
+
193
+ ```ts
194
+ const ai = wrapOpenAI(openai, usageTap, {
195
+ defaultContext: { customerId: "cust_123", feature: "chat.send" },
196
+ promptCompression: {
197
+ provider: "usagetap",
198
+ aggressiveness: { user: 0.5, system: 0.5, tool: 0.5 },
199
+ },
200
+ });
201
+ ```
202
+
203
+ `UsageTapClient` sends your UsageTap API key by default. Override `usageTapCompressionEndpoint` for single-text compression or `usageTapCompressionMessagesEndpoint` for wrapper message compression.
204
+
205
+ When using The Token Company, configure `tokenCompanyApiKey` on `UsageTapClient` and set `provider: "thetokencompany"`. Optional `tokenCompanyModel`, `aggressiveness`, and `tokenCompanyAppId` are supported at the client, manual `promptCompress`, and wrapper levels. Use `protectPromptText()` for text that must be passed through unchanged by compression-compatible providers.
182
206
 
183
207
  For advanced custom flows, `compressPromptInput(input, options?)` returns compression results without recording telemetry, and `recordPromptCompression({ callId, promptCompression })` records precomputed savings metadata against a call.
184
208
 
@@ -268,6 +268,18 @@ async function compressAnthropicParams(params, usageTap, compression, signal) {
268
268
  }
269
269
  const source = cloneRecord(params);
270
270
  const segments = [];
271
+ if (shouldUseUsageTapMessageEndpoint(compression)) {
272
+ const result = await usageTap.compressPromptMessages(source, {
273
+ provider: "usagetap",
274
+ failOpen: compression.failOpen,
275
+ aggressiveness: resolveMessageEndpointAggressiveness(compression),
276
+ signal
277
+ });
278
+ return {
279
+ params: result.compressedInput,
280
+ segments: [{ role: "user", result }]
281
+ };
282
+ }
271
283
  if (typeof source.system === "string") {
272
284
  const compressed = await compressTextForRole(
273
285
  source.system,
@@ -441,8 +453,11 @@ async function compressTextForRole(text, role, usageTap, compression, signal) {
441
453
  provider: roleOptions.provider,
442
454
  failOpen: roleOptions.failOpen,
443
455
  tokenCompanyModel: roleOptions.tokenCompanyModel,
456
+ aggressiveness: roleOptions.aggressiveness,
444
457
  tokenCompanyAggressiveness: roleOptions.tokenCompanyAggressiveness,
445
458
  tokenCompanyAppId: roleOptions.tokenCompanyAppId,
459
+ usageTapCompressionModel: roleOptions.usageTapCompressionModel,
460
+ usageTapCompressionAggressiveness: roleOptions.usageTapCompressionAggressiveness,
446
461
  signal
447
462
  });
448
463
  const compressedText = typeof result.compressedInput === "string" ? result.compressedInput : String(result.compressedInput);
@@ -501,16 +516,67 @@ function resolveRoleCompressionOptions(compression, role) {
501
516
  minTokens: roleOptions?.minTokens ?? compression.minTokens,
502
517
  failOpen: compression.failOpen,
503
518
  tokenCompanyModel: compression.tokenCompanyModel,
519
+ aggressiveness: roleOptions?.aggressiveness ?? resolveAggressiveness(compression, role),
504
520
  tokenCompanyAggressiveness: roleOptions?.tokenCompanyAggressiveness ?? resolveTokenCompanyAggressiveness(compression, role),
505
- tokenCompanyAppId: compression.tokenCompanyAppId
521
+ tokenCompanyAppId: compression.tokenCompanyAppId,
522
+ usageTapCompressionModel: compression.usageTapCompressionModel,
523
+ usageTapCompressionAggressiveness: roleOptions?.usageTapCompressionAggressiveness ?? resolveUsageTapCompressionAggressiveness(compression, role)
506
524
  };
507
525
  }
526
+ function resolveAggressiveness(compression, role) {
527
+ if (typeof compression.aggressiveness === "number") {
528
+ return compression.aggressiveness;
529
+ }
530
+ return compression.aggressiveness?.[role];
531
+ }
508
532
  function resolveTokenCompanyAggressiveness(compression, role) {
509
533
  if (typeof compression.tokenCompanyAggressiveness === "number") {
510
534
  return compression.tokenCompanyAggressiveness;
511
535
  }
512
536
  return compression.tokenCompanyAggressiveness?.[role];
513
537
  }
538
+ function resolveUsageTapCompressionAggressiveness(compression, role) {
539
+ if (typeof compression.usageTapCompressionAggressiveness === "number") {
540
+ return compression.usageTapCompressionAggressiveness;
541
+ }
542
+ return compression.usageTapCompressionAggressiveness?.[role];
543
+ }
544
+ function shouldUseUsageTapMessageEndpoint(compression) {
545
+ if (compression.provider !== "usagetap") {
546
+ return false;
547
+ }
548
+ return Object.values(compression.roles ?? {}).every((setting) => {
549
+ if (typeof setting !== "object" || setting === null) {
550
+ return true;
551
+ }
552
+ return setting.provider === void 0 || setting.provider === "usagetap";
553
+ });
554
+ }
555
+ function resolveMessageEndpointAggressiveness(compression) {
556
+ const base = compression.aggressiveness ?? compression.usageTapCompressionAggressiveness ?? compression.tokenCompanyAggressiveness;
557
+ if (typeof base === "number" || base === void 0) {
558
+ return hasExplicitEnabledRoles(compression) ? buildRoleAggressiveness(compression, base) : base;
559
+ }
560
+ return buildRoleAggressiveness(compression, void 0, base);
561
+ }
562
+ function hasExplicitEnabledRoles(compression) {
563
+ return Object.values(compression.roles ?? {}).some((setting) => setting !== false);
564
+ }
565
+ function buildRoleAggressiveness(compression, fallback, base = {}) {
566
+ const roles = ["system", "user", "tool", "assistant"];
567
+ const result = {};
568
+ for (const role of roles) {
569
+ const roleOptions = resolveRoleCompressionOptions(compression, role);
570
+ if (!roleOptions) {
571
+ continue;
572
+ }
573
+ const roleAggressiveness = roleOptions.aggressiveness ?? roleOptions.usageTapCompressionAggressiveness ?? roleOptions.tokenCompanyAggressiveness ?? base[role] ?? fallback;
574
+ if (roleAggressiveness !== void 0) {
575
+ result[role] = roleAggressiveness;
576
+ }
577
+ }
578
+ return result;
579
+ }
514
580
  function buildPromptCompressionTelemetry(segments) {
515
581
  if (!segments.length) {
516
582
  return void 0;