@diogonzafe/tokenwatch 0.8.0 → 0.9.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.
@@ -1,4 +1,4 @@
1
- import { I as IExporter, U as UsageEntry } from './index-CFBI-1ab.cjs';
1
+ import { I as IExporter, U as UsageEntry } from './index-fD5QLTWg.cjs';
2
2
 
3
3
  interface OTelAttributes {
4
4
  [key: string]: string | number | boolean | undefined;
@@ -1,4 +1,4 @@
1
- import { I as IExporter, U as UsageEntry } from './index-CFBI-1ab.js';
1
+ import { I as IExporter, U as UsageEntry } from './index-fD5QLTWg.js';
2
2
 
3
3
  interface OTelAttributes {
4
4
  [key: string]: string | number | boolean | undefined;
@@ -65,6 +65,10 @@ interface TrackerConfig {
65
65
  anomalyDetection?: AnomalyDetectionConfig;
66
66
  /** Custom exporter called after every tracked call (e.g. OTelExporter) */
67
67
  exporter?: IExporter;
68
+ /** TokenWatch Cloud API key — mirrors every tracked call to the cloud dashboard (fire-and-forget) */
69
+ cloudApiKey?: string;
70
+ /** Override the cloud ingest endpoint (default: https://api.tokenwatch.dev/v1/ingest) */
71
+ cloudEndpoint?: string;
68
72
  }
69
73
  interface UsageEntry {
70
74
  model: string;
@@ -65,6 +65,10 @@ interface TrackerConfig {
65
65
  anomalyDetection?: AnomalyDetectionConfig;
66
66
  /** Custom exporter called after every tracked call (e.g. OTelExporter) */
67
67
  exporter?: IExporter;
68
+ /** TokenWatch Cloud API key — mirrors every tracked call to the cloud dashboard (fire-and-forget) */
69
+ cloudApiKey?: string;
70
+ /** Override the cloud ingest endpoint (default: https://api.tokenwatch.dev/v1/ingest) */
71
+ cloudEndpoint?: string;
68
72
  }
69
73
  interface UsageEntry {
70
74
  model: string;
package/dist/index.cjs CHANGED
@@ -64,6 +64,40 @@ function calculateCost(inputTokens, outputTokens, price, cachedTokens = 0, cache
64
64
  return regularInputCost + cachedReadCost + cacheCreationCost + outputCost;
65
65
  }
66
66
 
67
+ // src/exporters/cloud.ts
68
+ var DEFAULT_ENDPOINT = "https://api.tokenwatch.dev/v1/ingest";
69
+ var CloudExporter = class {
70
+ constructor(apiKey, endpoint) {
71
+ this.apiKey = apiKey;
72
+ this.endpoint = endpoint ?? DEFAULT_ENDPOINT;
73
+ }
74
+ apiKey;
75
+ endpoint;
76
+ export(entry) {
77
+ fetch(this.endpoint, {
78
+ method: "POST",
79
+ headers: {
80
+ "Content-Type": "application/json",
81
+ Authorization: `Bearer ${this.apiKey}`
82
+ },
83
+ body: JSON.stringify({
84
+ model: entry.model,
85
+ inputTokens: entry.inputTokens,
86
+ outputTokens: entry.outputTokens,
87
+ reasoningTokens: entry.reasoningTokens ?? 0,
88
+ cachedTokens: entry.cachedTokens ?? 0,
89
+ cacheCreationTokens: entry.cacheCreationTokens ?? 0,
90
+ costUSD: entry.costUSD,
91
+ sessionId: entry.sessionId,
92
+ userId: entry.userId,
93
+ feature: entry.feature,
94
+ timestamp: entry.timestamp
95
+ })
96
+ }).catch(() => {
97
+ });
98
+ }
99
+ };
100
+
67
101
  // src/core/suggestions.ts
68
102
  var PROVIDER_PREFIXES = ["gpt-", "claude-", "gemini-", "deepseek-"];
69
103
  function getProviderPrefix(model) {
@@ -1725,7 +1759,9 @@ var TrackerConfigSchema = import_zod.z.object({
1725
1759
  mode: import_zod.z.enum(["once", "always"]).optional().default("once")
1726
1760
  }).optional(),
1727
1761
  exporter: import_zod.z.custom((v) => v !== null && typeof v === "object" && typeof v.export === "function").optional(),
1728
- appId: import_zod.z.string().optional()
1762
+ appId: import_zod.z.string().optional(),
1763
+ cloudApiKey: import_zod.z.string().optional(),
1764
+ cloudEndpoint: import_zod.z.string().url().optional()
1729
1765
  });
1730
1766
  function createTracker(config = {}) {
1731
1767
  const parsed = TrackerConfigSchema.safeParse(config);
@@ -1745,9 +1781,12 @@ ${issues}`);
1745
1781
  suggestions,
1746
1782
  anomalyDetection,
1747
1783
  exporter,
1748
- appId
1784
+ appId,
1785
+ cloudApiKey,
1786
+ cloudEndpoint
1749
1787
  } = parsed.data;
1750
1788
  const storage = typeof storageOption === "object" ? storageOption : createStorage(storageOption);
1789
+ const cloudExporter = cloudApiKey ? new CloudExporter(cloudApiKey, cloudEndpoint) : null;
1751
1790
  let remotePrices;
1752
1791
  let pricesUpdatedAt = bundledUpdatedAt;
1753
1792
  if (syncPrices) {
@@ -1808,6 +1847,9 @@ ${issues}`);
1808
1847
  Promise.resolve(exporter.export(full)).catch(() => {
1809
1848
  });
1810
1849
  }
1850
+ if (cloudExporter) {
1851
+ cloudExporter.export(full);
1852
+ }
1811
1853
  maybeFireAlerts(full);
1812
1854
  if (anomalyDetection) maybeDetectAnomaly(full);
1813
1855
  if (suggestions) {