@diogonzafe/tokenwatch 0.7.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.
- package/README.md +13 -10
- package/dist/adapters.cjs +17 -6
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.d.cts +2 -1
- package/dist/adapters.d.ts +2 -1
- package/dist/adapters.js +17 -6
- package/dist/adapters.js.map +1 -1
- package/dist/cli.js +1622 -518
- package/dist/cli.js.map +1 -1
- package/dist/exporters.d.cts +1 -1
- package/dist/exporters.d.ts +1 -1
- package/dist/{index-D9xq0RNg.d.cts → index-fD5QLTWg.d.cts} +16 -0
- package/dist/{index-D9xq0RNg.d.ts → index-fD5QLTWg.d.ts} +16 -0
- package/dist/index.cjs +164 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +164 -17
- package/dist/index.js.map +1 -1
- package/dist/langchain.d.cts +1 -1
- package/dist/langchain.d.ts +1 -1
- package/package.json +2 -2
- package/prices.json +96 -9
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-
|
|
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-
|
|
1
|
+
import { T as TrackerConfig, a as Tracker, L as LazyTracker, b as TrackingMeta } from './index-fD5QLTWg.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-fD5QLTWg.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-
|
|
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-
|
|
1
|
+
import { T as TrackerConfig, a as Tracker, L as LazyTracker, b as TrackingMeta } from './index-fD5QLTWg.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-fD5QLTWg.js';
|
|
3
3
|
|
|
4
4
|
declare function createTracker(config?: TrackerConfig): Tracker;
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -33,6 +33,40 @@ function calculateCost(inputTokens, outputTokens, price, cachedTokens = 0, cache
|
|
|
33
33
|
return regularInputCost + cachedReadCost + cacheCreationCost + outputCost;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
// src/exporters/cloud.ts
|
|
37
|
+
var DEFAULT_ENDPOINT = "https://api.tokenwatch.dev/v1/ingest";
|
|
38
|
+
var CloudExporter = class {
|
|
39
|
+
constructor(apiKey, endpoint) {
|
|
40
|
+
this.apiKey = apiKey;
|
|
41
|
+
this.endpoint = endpoint ?? DEFAULT_ENDPOINT;
|
|
42
|
+
}
|
|
43
|
+
apiKey;
|
|
44
|
+
endpoint;
|
|
45
|
+
export(entry) {
|
|
46
|
+
fetch(this.endpoint, {
|
|
47
|
+
method: "POST",
|
|
48
|
+
headers: {
|
|
49
|
+
"Content-Type": "application/json",
|
|
50
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
51
|
+
},
|
|
52
|
+
body: JSON.stringify({
|
|
53
|
+
model: entry.model,
|
|
54
|
+
inputTokens: entry.inputTokens,
|
|
55
|
+
outputTokens: entry.outputTokens,
|
|
56
|
+
reasoningTokens: entry.reasoningTokens ?? 0,
|
|
57
|
+
cachedTokens: entry.cachedTokens ?? 0,
|
|
58
|
+
cacheCreationTokens: entry.cacheCreationTokens ?? 0,
|
|
59
|
+
costUSD: entry.costUSD,
|
|
60
|
+
sessionId: entry.sessionId,
|
|
61
|
+
userId: entry.userId,
|
|
62
|
+
feature: entry.feature,
|
|
63
|
+
timestamp: entry.timestamp
|
|
64
|
+
})
|
|
65
|
+
}).catch(() => {
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
36
70
|
// src/core/suggestions.ts
|
|
37
71
|
var PROVIDER_PREFIXES = ["gpt-", "claude-", "gemini-", "deepseek-"];
|
|
38
72
|
function getProviderPrefix(model) {
|
|
@@ -122,6 +156,7 @@ var SqliteStorage = class {
|
|
|
122
156
|
session_id TEXT,
|
|
123
157
|
user_id TEXT,
|
|
124
158
|
feature TEXT,
|
|
159
|
+
app_id TEXT,
|
|
125
160
|
timestamp TEXT NOT NULL
|
|
126
161
|
)
|
|
127
162
|
`);
|
|
@@ -138,13 +173,16 @@ var SqliteStorage = class {
|
|
|
138
173
|
if (!cols.includes("cache_creation_tokens")) {
|
|
139
174
|
this.db.exec(`ALTER TABLE usage ADD COLUMN cache_creation_tokens INTEGER NOT NULL DEFAULT 0`);
|
|
140
175
|
}
|
|
176
|
+
if (!cols.includes("app_id")) {
|
|
177
|
+
this.db.exec(`ALTER TABLE usage ADD COLUMN app_id TEXT`);
|
|
178
|
+
}
|
|
141
179
|
}
|
|
142
180
|
record(entry) {
|
|
143
181
|
this.db.prepare(
|
|
144
182
|
`INSERT INTO usage
|
|
145
183
|
(model, input_tokens, output_tokens, reasoning_tokens, cached_tokens, cache_creation_tokens,
|
|
146
|
-
cost_usd, session_id, user_id, feature, timestamp)
|
|
147
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
184
|
+
cost_usd, session_id, user_id, feature, app_id, timestamp)
|
|
185
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
|
148
186
|
).run(
|
|
149
187
|
entry.model,
|
|
150
188
|
entry.inputTokens,
|
|
@@ -156,6 +194,7 @@ var SqliteStorage = class {
|
|
|
156
194
|
entry.sessionId ?? null,
|
|
157
195
|
entry.userId ?? null,
|
|
158
196
|
entry.feature ?? null,
|
|
197
|
+
entry.appId ?? null,
|
|
159
198
|
entry.timestamp
|
|
160
199
|
);
|
|
161
200
|
}
|
|
@@ -172,6 +211,7 @@ var SqliteStorage = class {
|
|
|
172
211
|
...r.session_id != null && { sessionId: r.session_id },
|
|
173
212
|
...r.user_id != null && { userId: r.user_id },
|
|
174
213
|
...r.feature != null && { feature: r.feature },
|
|
214
|
+
...r.app_id != null && { appId: r.app_id },
|
|
175
215
|
timestamp: r.timestamp
|
|
176
216
|
}));
|
|
177
217
|
}
|
|
@@ -237,7 +277,7 @@ async function getRemotePrices() {
|
|
|
237
277
|
|
|
238
278
|
// prices.json
|
|
239
279
|
var prices_default = {
|
|
240
|
-
updated_at: "2026-
|
|
280
|
+
updated_at: "2026-06-09",
|
|
241
281
|
source: "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",
|
|
242
282
|
models: {
|
|
243
283
|
"gpt-4o": {
|
|
@@ -281,14 +321,12 @@ var prices_default = {
|
|
|
281
321
|
input: 3,
|
|
282
322
|
output: 15,
|
|
283
323
|
cachedInput: 0.3,
|
|
284
|
-
|
|
285
|
-
maxInputTokens: 1e6
|
|
324
|
+
maxInputTokens: 2e5
|
|
286
325
|
},
|
|
287
326
|
"claude-haiku-4-5": {
|
|
288
327
|
input: 1,
|
|
289
328
|
output: 5,
|
|
290
329
|
cachedInput: 0.1,
|
|
291
|
-
cacheCreationInput: 1.25,
|
|
292
330
|
maxInputTokens: 2e5
|
|
293
331
|
},
|
|
294
332
|
"gemini-2.5-pro": {
|
|
@@ -340,7 +378,6 @@ var prices_default = {
|
|
|
340
378
|
input: 3,
|
|
341
379
|
output: 15,
|
|
342
380
|
cachedInput: 0.3,
|
|
343
|
-
cacheCreationInput: 3.75,
|
|
344
381
|
maxInputTokens: 2e5
|
|
345
382
|
},
|
|
346
383
|
"gpt-oss-120b": {
|
|
@@ -833,9 +870,9 @@ var prices_default = {
|
|
|
833
870
|
maxInputTokens: 163840
|
|
834
871
|
},
|
|
835
872
|
"deepseek-r1": {
|
|
836
|
-
input:
|
|
837
|
-
output:
|
|
838
|
-
maxInputTokens:
|
|
873
|
+
input: 1.35,
|
|
874
|
+
output: 5.4,
|
|
875
|
+
maxInputTokens: 128e3
|
|
839
876
|
},
|
|
840
877
|
"deepseek-v3": {
|
|
841
878
|
input: 0.27,
|
|
@@ -1275,7 +1312,7 @@ var prices_default = {
|
|
|
1275
1312
|
"deepseek-r1-distill-llama-70b": {
|
|
1276
1313
|
input: 0.99,
|
|
1277
1314
|
output: 0.99,
|
|
1278
|
-
maxInputTokens:
|
|
1315
|
+
maxInputTokens: 32768
|
|
1279
1316
|
},
|
|
1280
1317
|
"deepseek-llama3.3-70b": {
|
|
1281
1318
|
input: 0.2,
|
|
@@ -1559,7 +1596,97 @@ var prices_default = {
|
|
|
1559
1596
|
input: 5,
|
|
1560
1597
|
output: 30,
|
|
1561
1598
|
cachedInput: 0.5,
|
|
1599
|
+
maxInputTokens: 105e4
|
|
1600
|
+
},
|
|
1601
|
+
"gpt-5.5-2026-04-23": {
|
|
1602
|
+
input: 5,
|
|
1603
|
+
output: 30,
|
|
1604
|
+
cachedInput: 0.5,
|
|
1605
|
+
maxInputTokens: 105e4
|
|
1606
|
+
},
|
|
1607
|
+
"gpt-5.5-pro": {
|
|
1608
|
+
input: 30,
|
|
1609
|
+
output: 180,
|
|
1610
|
+
cachedInput: 3,
|
|
1611
|
+
maxInputTokens: 105e4
|
|
1612
|
+
},
|
|
1613
|
+
"gpt-5.5-pro-2026-04-23": {
|
|
1614
|
+
input: 30,
|
|
1615
|
+
output: 180,
|
|
1616
|
+
cachedInput: 3,
|
|
1617
|
+
maxInputTokens: 105e4
|
|
1618
|
+
},
|
|
1619
|
+
"gpt-5.4-mini-2026-03-17": {
|
|
1620
|
+
input: 0.75,
|
|
1621
|
+
output: 4.5,
|
|
1622
|
+
cachedInput: 0.075,
|
|
1623
|
+
maxInputTokens: 272e3
|
|
1624
|
+
},
|
|
1625
|
+
"gpt-5.4-nano-2026-03-17": {
|
|
1626
|
+
input: 0.2,
|
|
1627
|
+
output: 1.25,
|
|
1628
|
+
cachedInput: 0.02,
|
|
1562
1629
|
maxInputTokens: 272e3
|
|
1630
|
+
},
|
|
1631
|
+
"gpt-image-2": {
|
|
1632
|
+
input: 5,
|
|
1633
|
+
output: 10,
|
|
1634
|
+
cachedInput: 1.25
|
|
1635
|
+
},
|
|
1636
|
+
"gpt-image-2-2026-04-21": {
|
|
1637
|
+
input: 5,
|
|
1638
|
+
output: 10,
|
|
1639
|
+
cachedInput: 1.25
|
|
1640
|
+
},
|
|
1641
|
+
"gpt-realtime-2": {
|
|
1642
|
+
input: 4,
|
|
1643
|
+
output: 16,
|
|
1644
|
+
cachedInput: 0.4,
|
|
1645
|
+
maxInputTokens: 32e3
|
|
1646
|
+
},
|
|
1647
|
+
"gemini-3.5-flash": {
|
|
1648
|
+
input: 1.5,
|
|
1649
|
+
output: 9,
|
|
1650
|
+
cachedInput: 0.15,
|
|
1651
|
+
maxInputTokens: 1048576
|
|
1652
|
+
},
|
|
1653
|
+
"gemini-3.1-flash-lite": {
|
|
1654
|
+
input: 0.25,
|
|
1655
|
+
output: 1.5,
|
|
1656
|
+
cachedInput: 0.025,
|
|
1657
|
+
maxInputTokens: 1048576
|
|
1658
|
+
},
|
|
1659
|
+
"claude-opus-4-8": {
|
|
1660
|
+
input: 5,
|
|
1661
|
+
output: 25,
|
|
1662
|
+
cachedInput: 0.5,
|
|
1663
|
+
cacheCreationInput: 6.25,
|
|
1664
|
+
maxInputTokens: 1e6
|
|
1665
|
+
},
|
|
1666
|
+
"claude-opus-4-8@default": {
|
|
1667
|
+
input: 5,
|
|
1668
|
+
output: 25,
|
|
1669
|
+
cachedInput: 0.5,
|
|
1670
|
+
cacheCreationInput: 6.25,
|
|
1671
|
+
maxInputTokens: 1e6
|
|
1672
|
+
},
|
|
1673
|
+
"claude-4-sonnet": {
|
|
1674
|
+
input: 3,
|
|
1675
|
+
output: 15,
|
|
1676
|
+
cachedInput: 0.3,
|
|
1677
|
+
maxInputTokens: 2e5
|
|
1678
|
+
},
|
|
1679
|
+
"claude-4-opus": {
|
|
1680
|
+
input: 5,
|
|
1681
|
+
output: 25,
|
|
1682
|
+
cachedInput: 0.5,
|
|
1683
|
+
maxInputTokens: 2e5
|
|
1684
|
+
},
|
|
1685
|
+
"claude-3-7-sonnet": {
|
|
1686
|
+
input: 3,
|
|
1687
|
+
output: 15,
|
|
1688
|
+
cachedInput: 0.3,
|
|
1689
|
+
maxInputTokens: 2e5
|
|
1563
1690
|
}
|
|
1564
1691
|
}
|
|
1565
1692
|
};
|
|
@@ -1599,7 +1726,10 @@ var TrackerConfigSchema = z.object({
|
|
|
1599
1726
|
windowHours: z.number().positive().optional().default(24),
|
|
1600
1727
|
mode: z.enum(["once", "always"]).optional().default("once")
|
|
1601
1728
|
}).optional(),
|
|
1602
|
-
exporter: z.custom((v) => v !== null && typeof v === "object" && typeof v.export === "function").optional()
|
|
1729
|
+
exporter: z.custom((v) => v !== null && typeof v === "object" && typeof v.export === "function").optional(),
|
|
1730
|
+
appId: z.string().optional(),
|
|
1731
|
+
cloudApiKey: z.string().optional(),
|
|
1732
|
+
cloudEndpoint: z.string().url().optional()
|
|
1603
1733
|
});
|
|
1604
1734
|
function createTracker(config = {}) {
|
|
1605
1735
|
const parsed = TrackerConfigSchema.safeParse(config);
|
|
@@ -1618,9 +1748,13 @@ ${issues}`);
|
|
|
1618
1748
|
budgets,
|
|
1619
1749
|
suggestions,
|
|
1620
1750
|
anomalyDetection,
|
|
1621
|
-
exporter
|
|
1751
|
+
exporter,
|
|
1752
|
+
appId,
|
|
1753
|
+
cloudApiKey,
|
|
1754
|
+
cloudEndpoint
|
|
1622
1755
|
} = parsed.data;
|
|
1623
1756
|
const storage = typeof storageOption === "object" ? storageOption : createStorage(storageOption);
|
|
1757
|
+
const cloudExporter = cloudApiKey ? new CloudExporter(cloudApiKey, cloudEndpoint) : null;
|
|
1624
1758
|
let remotePrices;
|
|
1625
1759
|
let pricesUpdatedAt = bundledUpdatedAt;
|
|
1626
1760
|
if (syncPrices) {
|
|
@@ -1673,13 +1807,17 @@ ${issues}`);
|
|
|
1673
1807
|
const full = {
|
|
1674
1808
|
...entry,
|
|
1675
1809
|
costUSD,
|
|
1676
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1810
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1811
|
+
...appId !== void 0 && entry.appId === void 0 && { appId }
|
|
1677
1812
|
};
|
|
1678
1813
|
storage.record(full);
|
|
1679
1814
|
if (exporter) {
|
|
1680
1815
|
Promise.resolve(exporter.export(full)).catch(() => {
|
|
1681
1816
|
});
|
|
1682
1817
|
}
|
|
1818
|
+
if (cloudExporter) {
|
|
1819
|
+
cloudExporter.export(full);
|
|
1820
|
+
}
|
|
1683
1821
|
maybeFireAlerts(full);
|
|
1684
1822
|
if (anomalyDetection) maybeDetectAnomaly(full);
|
|
1685
1823
|
if (suggestions) {
|
|
@@ -1760,6 +1898,7 @@ ${issues}`);
|
|
|
1760
1898
|
const bySession = {};
|
|
1761
1899
|
const byUser = {};
|
|
1762
1900
|
const byFeature = {};
|
|
1901
|
+
const byApp = {};
|
|
1763
1902
|
let totalInput = 0;
|
|
1764
1903
|
let totalOutput = 0;
|
|
1765
1904
|
let totalCost = 0;
|
|
@@ -1796,6 +1935,11 @@ ${issues}`);
|
|
|
1796
1935
|
f.costUSD += e.costUSD;
|
|
1797
1936
|
f.calls += 1;
|
|
1798
1937
|
}
|
|
1938
|
+
if (e.appId) {
|
|
1939
|
+
const a = byApp[e.appId] ??= { costUSD: 0, calls: 0 };
|
|
1940
|
+
a.costUSD += e.costUSD;
|
|
1941
|
+
a.calls += 1;
|
|
1942
|
+
}
|
|
1799
1943
|
}
|
|
1800
1944
|
if (options && entries.length > 0) {
|
|
1801
1945
|
periodFrom = entries[0]?.timestamp ?? periodFrom;
|
|
@@ -1807,6 +1951,7 @@ ${issues}`);
|
|
|
1807
1951
|
bySession,
|
|
1808
1952
|
byUser,
|
|
1809
1953
|
byFeature,
|
|
1954
|
+
byApp,
|
|
1810
1955
|
period: { from: periodFrom, to: lastTimestamp },
|
|
1811
1956
|
...pricesUpdatedAt ? { pricesUpdatedAt } : {}
|
|
1812
1957
|
};
|
|
@@ -1911,7 +2056,7 @@ ${issues}`);
|
|
|
1911
2056
|
}
|
|
1912
2057
|
async function exportCSV() {
|
|
1913
2058
|
const entries = await Promise.resolve(storage.getAll());
|
|
1914
|
-
const header = "timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature";
|
|
2059
|
+
const header = "timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature,appId";
|
|
1915
2060
|
const rows = entries.map(
|
|
1916
2061
|
(e) => [
|
|
1917
2062
|
csvEscape(e.timestamp),
|
|
@@ -1924,7 +2069,8 @@ ${issues}`);
|
|
|
1924
2069
|
e.costUSD.toFixed(8),
|
|
1925
2070
|
csvEscape(e.sessionId ?? ""),
|
|
1926
2071
|
csvEscape(e.userId ?? ""),
|
|
1927
|
-
csvEscape(e.feature ?? "")
|
|
2072
|
+
csvEscape(e.feature ?? ""),
|
|
2073
|
+
csvEscape(e.appId ?? "")
|
|
1928
2074
|
].join(",")
|
|
1929
2075
|
);
|
|
1930
2076
|
return [header, ...rows].join("\n");
|
|
@@ -1985,7 +2131,7 @@ function csvEscape(value) {
|
|
|
1985
2131
|
}
|
|
1986
2132
|
|
|
1987
2133
|
// src/core/lazy-tracker.ts
|
|
1988
|
-
var CSV_HEADER = "timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature";
|
|
2134
|
+
var CSV_HEADER = "timestamp,model,inputTokens,outputTokens,reasoningTokens,cachedTokens,cacheCreationTokens,costUSD,sessionId,userId,feature,appId";
|
|
1989
2135
|
function emptyReport() {
|
|
1990
2136
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1991
2137
|
return {
|
|
@@ -1995,6 +2141,7 @@ function emptyReport() {
|
|
|
1995
2141
|
bySession: {},
|
|
1996
2142
|
byUser: {},
|
|
1997
2143
|
byFeature: {},
|
|
2144
|
+
byApp: {},
|
|
1998
2145
|
period: { from: now, to: now }
|
|
1999
2146
|
};
|
|
2000
2147
|
}
|