@diogonzafe/tokenwatch 0.7.0 → 0.8.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.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TrackerConfig, a as Tracker, L as LazyTracker, b as TrackingMeta } from './index-D9xq0RNg.cjs';
2
- export { A as AnomalyDetectionConfig, B as BudgetConfig, C as CostForecast, F as FeatureStats, c as ForecastOptions, I as IExporter, d as IStorage, M as ModelPrice, e as ModelStats, P as PriceMap, f as PricesFile, R as Report, g as ReportOptions, S as SessionStats, U as UsageEntry, h as UserStats } from './index-D9xq0RNg.cjs';
1
+ import { T as TrackerConfig, a as Tracker, L as LazyTracker, b as TrackingMeta } from './index-CFBI-1ab.cjs';
2
+ export { A as AnomalyDetectionConfig, B as BudgetConfig, C as CostForecast, F as FeatureStats, c as ForecastOptions, I as IExporter, d as IStorage, M as ModelPrice, e as ModelStats, P as PriceMap, f as PricesFile, R as Report, g as ReportOptions, S as SessionStats, U as UsageEntry, h as UserStats } from './index-CFBI-1ab.cjs';
3
3
 
4
4
  declare function createTracker(config?: TrackerConfig): Tracker;
5
5
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { T as TrackerConfig, a as Tracker, L as LazyTracker, b as TrackingMeta } from './index-D9xq0RNg.js';
2
- export { A as AnomalyDetectionConfig, B as BudgetConfig, C as CostForecast, F as FeatureStats, c as ForecastOptions, I as IExporter, d as IStorage, M as ModelPrice, e as ModelStats, P as PriceMap, f as PricesFile, R as Report, g as ReportOptions, S as SessionStats, U as UsageEntry, h as UserStats } from './index-D9xq0RNg.js';
1
+ import { T as TrackerConfig, a as Tracker, L as LazyTracker, b as TrackingMeta } from './index-CFBI-1ab.js';
2
+ export { A as AnomalyDetectionConfig, B as BudgetConfig, C as CostForecast, F as FeatureStats, c as ForecastOptions, I as IExporter, d as IStorage, M as ModelPrice, e as ModelStats, P as PriceMap, f as PricesFile, R as Report, g as ReportOptions, S as SessionStats, U as UsageEntry, h as UserStats } from './index-CFBI-1ab.js';
3
3
 
4
4
  declare function createTracker(config?: TrackerConfig): Tracker;
5
5
 
package/dist/index.js CHANGED
@@ -122,6 +122,7 @@ var SqliteStorage = class {
122
122
  session_id TEXT,
123
123
  user_id TEXT,
124
124
  feature TEXT,
125
+ app_id TEXT,
125
126
  timestamp TEXT NOT NULL
126
127
  )
127
128
  `);
@@ -138,13 +139,16 @@ var SqliteStorage = class {
138
139
  if (!cols.includes("cache_creation_tokens")) {
139
140
  this.db.exec(`ALTER TABLE usage ADD COLUMN cache_creation_tokens INTEGER NOT NULL DEFAULT 0`);
140
141
  }
142
+ if (!cols.includes("app_id")) {
143
+ this.db.exec(`ALTER TABLE usage ADD COLUMN app_id TEXT`);
144
+ }
141
145
  }
142
146
  record(entry) {
143
147
  this.db.prepare(
144
148
  `INSERT INTO usage
145
149
  (model, input_tokens, output_tokens, reasoning_tokens, cached_tokens, cache_creation_tokens,
146
- cost_usd, session_id, user_id, feature, timestamp)
147
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
150
+ cost_usd, session_id, user_id, feature, app_id, timestamp)
151
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
148
152
  ).run(
149
153
  entry.model,
150
154
  entry.inputTokens,
@@ -156,6 +160,7 @@ var SqliteStorage = class {
156
160
  entry.sessionId ?? null,
157
161
  entry.userId ?? null,
158
162
  entry.feature ?? null,
163
+ entry.appId ?? null,
159
164
  entry.timestamp
160
165
  );
161
166
  }
@@ -172,6 +177,7 @@ var SqliteStorage = class {
172
177
  ...r.session_id != null && { sessionId: r.session_id },
173
178
  ...r.user_id != null && { userId: r.user_id },
174
179
  ...r.feature != null && { feature: r.feature },
180
+ ...r.app_id != null && { appId: r.app_id },
175
181
  timestamp: r.timestamp
176
182
  }));
177
183
  }
@@ -237,7 +243,7 @@ async function getRemotePrices() {
237
243
 
238
244
  // prices.json
239
245
  var prices_default = {
240
- updated_at: "2026-04-24",
246
+ updated_at: "2026-06-09",
241
247
  source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
242
248
  models: {
243
249
  "gpt-4o": {
@@ -281,14 +287,12 @@ var prices_default = {
281
287
  input: 3,
282
288
  output: 15,
283
289
  cachedInput: 0.3,
284
- cacheCreationInput: 3.75,
285
- maxInputTokens: 1e6
290
+ maxInputTokens: 2e5
286
291
  },
287
292
  "claude-haiku-4-5": {
288
293
  input: 1,
289
294
  output: 5,
290
295
  cachedInput: 0.1,
291
- cacheCreationInput: 1.25,
292
296
  maxInputTokens: 2e5
293
297
  },
294
298
  "gemini-2.5-pro": {
@@ -340,7 +344,6 @@ var prices_default = {
340
344
  input: 3,
341
345
  output: 15,
342
346
  cachedInput: 0.3,
343
- cacheCreationInput: 3.75,
344
347
  maxInputTokens: 2e5
345
348
  },
346
349
  "gpt-oss-120b": {
@@ -833,9 +836,9 @@ var prices_default = {
833
836
  maxInputTokens: 163840
834
837
  },
835
838
  "deepseek-r1": {
836
- input: 0.55,
837
- output: 2.19,
838
- maxInputTokens: 65536
839
+ input: 1.35,
840
+ output: 5.4,
841
+ maxInputTokens: 128e3
839
842
  },
840
843
  "deepseek-v3": {
841
844
  input: 0.27,
@@ -1275,7 +1278,7 @@ var prices_default = {
1275
1278
  "deepseek-r1-distill-llama-70b": {
1276
1279
  input: 0.99,
1277
1280
  output: 0.99,
1278
- maxInputTokens: 8e3
1281
+ maxInputTokens: 32768
1279
1282
  },
1280
1283
  "deepseek-llama3.3-70b": {
1281
1284
  input: 0.2,
@@ -1559,7 +1562,97 @@ var prices_default = {
1559
1562
  input: 5,
1560
1563
  output: 30,
1561
1564
  cachedInput: 0.5,
1565
+ maxInputTokens: 105e4
1566
+ },
1567
+ "gpt-5.5-2026-04-23": {
1568
+ input: 5,
1569
+ output: 30,
1570
+ cachedInput: 0.5,
1571
+ maxInputTokens: 105e4
1572
+ },
1573
+ "gpt-5.5-pro": {
1574
+ input: 30,
1575
+ output: 180,
1576
+ cachedInput: 3,
1577
+ maxInputTokens: 105e4
1578
+ },
1579
+ "gpt-5.5-pro-2026-04-23": {
1580
+ input: 30,
1581
+ output: 180,
1582
+ cachedInput: 3,
1583
+ maxInputTokens: 105e4
1584
+ },
1585
+ "gpt-5.4-mini-2026-03-17": {
1586
+ input: 0.75,
1587
+ output: 4.5,
1588
+ cachedInput: 0.075,
1562
1589
  maxInputTokens: 272e3
1590
+ },
1591
+ "gpt-5.4-nano-2026-03-17": {
1592
+ input: 0.2,
1593
+ output: 1.25,
1594
+ cachedInput: 0.02,
1595
+ maxInputTokens: 272e3
1596
+ },
1597
+ "gpt-image-2": {
1598
+ input: 5,
1599
+ output: 10,
1600
+ cachedInput: 1.25
1601
+ },
1602
+ "gpt-image-2-2026-04-21": {
1603
+ input: 5,
1604
+ output: 10,
1605
+ cachedInput: 1.25
1606
+ },
1607
+ "gpt-realtime-2": {
1608
+ input: 4,
1609
+ output: 16,
1610
+ cachedInput: 0.4,
1611
+ maxInputTokens: 32e3
1612
+ },
1613
+ "gemini-3.5-flash": {
1614
+ input: 1.5,
1615
+ output: 9,
1616
+ cachedInput: 0.15,
1617
+ maxInputTokens: 1048576
1618
+ },
1619
+ "gemini-3.1-flash-lite": {
1620
+ input: 0.25,
1621
+ output: 1.5,
1622
+ cachedInput: 0.025,
1623
+ maxInputTokens: 1048576
1624
+ },
1625
+ "claude-opus-4-8": {
1626
+ input: 5,
1627
+ output: 25,
1628
+ cachedInput: 0.5,
1629
+ cacheCreationInput: 6.25,
1630
+ maxInputTokens: 1e6
1631
+ },
1632
+ "claude-opus-4-8@default": {
1633
+ input: 5,
1634
+ output: 25,
1635
+ cachedInput: 0.5,
1636
+ cacheCreationInput: 6.25,
1637
+ maxInputTokens: 1e6
1638
+ },
1639
+ "claude-4-sonnet": {
1640
+ input: 3,
1641
+ output: 15,
1642
+ cachedInput: 0.3,
1643
+ maxInputTokens: 2e5
1644
+ },
1645
+ "claude-4-opus": {
1646
+ input: 5,
1647
+ output: 25,
1648
+ cachedInput: 0.5,
1649
+ maxInputTokens: 2e5
1650
+ },
1651
+ "claude-3-7-sonnet": {
1652
+ input: 3,
1653
+ output: 15,
1654
+ cachedInput: 0.3,
1655
+ maxInputTokens: 2e5
1563
1656
  }
1564
1657
  }
1565
1658
  };
@@ -1599,7 +1692,8 @@ var TrackerConfigSchema = z.object({
1599
1692
  windowHours: z.number().positive().optional().default(24),
1600
1693
  mode: z.enum(["once", "always"]).optional().default("once")
1601
1694
  }).optional(),
1602
- exporter: z.custom((v) => v !== null && typeof v === "object" && typeof v.export === "function").optional()
1695
+ exporter: z.custom((v) => v !== null && typeof v === "object" && typeof v.export === "function").optional(),
1696
+ appId: z.string().optional()
1603
1697
  });
1604
1698
  function createTracker(config = {}) {
1605
1699
  const parsed = TrackerConfigSchema.safeParse(config);
@@ -1618,7 +1712,8 @@ ${issues}`);
1618
1712
  budgets,
1619
1713
  suggestions,
1620
1714
  anomalyDetection,
1621
- exporter
1715
+ exporter,
1716
+ appId
1622
1717
  } = parsed.data;
1623
1718
  const storage = typeof storageOption === "object" ? storageOption : createStorage(storageOption);
1624
1719
  let remotePrices;
@@ -1673,7 +1768,8 @@ ${issues}`);
1673
1768
  const full = {
1674
1769
  ...entry,
1675
1770
  costUSD,
1676
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1771
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1772
+ ...appId !== void 0 && entry.appId === void 0 && { appId }
1677
1773
  };
1678
1774
  storage.record(full);
1679
1775
  if (exporter) {
@@ -1760,6 +1856,7 @@ ${issues}`);
1760
1856
  const bySession = {};
1761
1857
  const byUser = {};
1762
1858
  const byFeature = {};
1859
+ const byApp = {};
1763
1860
  let totalInput = 0;
1764
1861
  let totalOutput = 0;
1765
1862
  let totalCost = 0;
@@ -1796,6 +1893,11 @@ ${issues}`);
1796
1893
  f.costUSD += e.costUSD;
1797
1894
  f.calls += 1;
1798
1895
  }
1896
+ if (e.appId) {
1897
+ const a = byApp[e.appId] ??= { costUSD: 0, calls: 0 };
1898
+ a.costUSD += e.costUSD;
1899
+ a.calls += 1;
1900
+ }
1799
1901
  }
1800
1902
  if (options && entries.length > 0) {
1801
1903
  periodFrom = entries[0]?.timestamp ?? periodFrom;
@@ -1807,6 +1909,7 @@ ${issues}`);
1807
1909
  bySession,
1808
1910
  byUser,
1809
1911
  byFeature,
1912
+ byApp,
1810
1913
  period: { from: periodFrom, to: lastTimestamp },
1811
1914
  ...pricesUpdatedAt ? { pricesUpdatedAt } : {}
1812
1915
  };
@@ -1911,7 +2014,7 @@ ${issues}`);
1911
2014
  }
1912
2015
  async function exportCSV() {
1913
2016
  const entries = await Promise.resolve(storage.getAll());
1914
- const header = "timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature";
2017
+ const header = "timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature,appId";
1915
2018
  const rows = entries.map(
1916
2019
  (e) => [
1917
2020
  csvEscape(e.timestamp),
@@ -1924,7 +2027,8 @@ ${issues}`);
1924
2027
  e.costUSD.toFixed(8),
1925
2028
  csvEscape(e.sessionId ?? ""),
1926
2029
  csvEscape(e.userId ?? ""),
1927
- csvEscape(e.feature ?? "")
2030
+ csvEscape(e.feature ?? ""),
2031
+ csvEscape(e.appId ?? "")
1928
2032
  ].join(",")
1929
2033
  );
1930
2034
  return [header, ...rows].join("\n");
@@ -1985,7 +2089,7 @@ function csvEscape(value) {
1985
2089
  }
1986
2090
 
1987
2091
  // src/core/lazy-tracker.ts
1988
- var CSV_HEADER = "timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature";
2092
+ var CSV_HEADER = "timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature,appId";
1989
2093
  function emptyReport() {
1990
2094
  const now = (/* @__PURE__ */ new Date()).toISOString();
1991
2095
  return {
@@ -1995,6 +2099,7 @@ function emptyReport() {
1995
2099
  bySession: {},
1996
2100
  byUser: {},
1997
2101
  byFeature: {},
2102
+ byApp: {},
1998
2103
  period: { from: now, to: now }
1999
2104
  };
2000
2105
  }