@diogonzafe/tokenwatch 0.1.17 → 0.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.
- package/README.md +22 -4
- package/dist/adapters.d.cts +1 -1
- package/dist/adapters.d.ts +1 -1
- package/dist/cli.cjs +18 -4
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +18 -4
- package/dist/cli.js.map +1 -1
- package/dist/{index-Cy_sl3FI.d.cts → index-BQZaFcHQ.d.cts} +14 -0
- package/dist/{index-Cy_sl3FI.d.ts → index-BQZaFcHQ.d.ts} +14 -0
- package/dist/index.cjs +102 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -8
- package/dist/index.d.ts +23 -8
- package/dist/index.js +102 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as TrackerConfig, a as Tracker, b as TrackingMeta } from './index-
|
|
2
|
-
export { I as IStorage, M as ModelPrice, c as ModelStats, P as PriceMap, d as PricesFile, R as Report, S as SessionStats, U as UsageEntry, e as UserStats } from './index-
|
|
1
|
+
import { T as TrackerConfig, a as Tracker, b as TrackingMeta } from './index-BQZaFcHQ.js';
|
|
2
|
+
export { I as IStorage, M as ModelPrice, c as ModelStats, P as PriceMap, d as PricesFile, R as Report, S as SessionStats, U as UsageEntry, e as UserStats } from './index-BQZaFcHQ.js';
|
|
3
3
|
|
|
4
4
|
declare function createTracker(config?: TrackerConfig): Tracker;
|
|
5
5
|
|
|
@@ -9,23 +9,31 @@ interface CompletionsLike {
|
|
|
9
9
|
interface ChatLike {
|
|
10
10
|
completions: CompletionsLike;
|
|
11
11
|
}
|
|
12
|
+
interface EmbeddingsLike {
|
|
13
|
+
create(params: Record<string, unknown>): Promise<unknown>;
|
|
14
|
+
}
|
|
12
15
|
type OpenAILike = {
|
|
13
16
|
chat: ChatLike;
|
|
17
|
+
embeddings?: EmbeddingsLike;
|
|
14
18
|
} & Record<string, unknown>;
|
|
15
19
|
type AugmentedCreate$1<TCreate extends (...args: any[]) => any> = (params: Parameters<TCreate>[0] & TrackingMeta) => ReturnType<TCreate>;
|
|
16
|
-
type WrappedOpenAI<T extends OpenAILike> = Omit<T, 'chat'> & {
|
|
20
|
+
type WrappedOpenAI<T extends OpenAILike> = Omit<T, 'chat' | 'embeddings'> & {
|
|
17
21
|
chat: Omit<T['chat'], 'completions'> & {
|
|
18
22
|
completions: Omit<T['chat']['completions'], 'create'> & {
|
|
19
23
|
create: AugmentedCreate$1<T['chat']['completions']['create']>;
|
|
20
24
|
};
|
|
21
25
|
};
|
|
26
|
+
embeddings: T['embeddings'] extends EmbeddingsLike ? Omit<T['embeddings'], 'create'> & {
|
|
27
|
+
create: AugmentedCreate$1<T['embeddings']['create']>;
|
|
28
|
+
} : T['embeddings'];
|
|
22
29
|
};
|
|
23
30
|
/**
|
|
24
31
|
* Wraps an OpenAI client (or any OpenAI-compatible client) to transparently
|
|
25
|
-
* intercept chat.completions.create calls and report
|
|
32
|
+
* intercept chat.completions.create and embeddings.create calls and report
|
|
33
|
+
* token usage to the tracker.
|
|
26
34
|
*
|
|
27
|
-
* The returned client is typed to accept __sessionId
|
|
28
|
-
* normal params — no type cast required at the call site.
|
|
35
|
+
* The returned client is typed to accept __sessionId, __userId, and __feature
|
|
36
|
+
* alongside the normal params — no type cast required at the call site.
|
|
29
37
|
*/
|
|
30
38
|
declare function wrapOpenAI<T extends OpenAILike>(client: T, tracker: Tracker): WrappedOpenAI<T>;
|
|
31
39
|
|
|
@@ -45,8 +53,12 @@ type WrappedAnthropic<T extends AnthropicLike> = Omit<T, 'messages'> & {
|
|
|
45
53
|
* Wraps an Anthropic client to transparently intercept messages.create calls
|
|
46
54
|
* and report token usage to the tracker.
|
|
47
55
|
*
|
|
48
|
-
* The returned client is typed to accept __sessionId
|
|
49
|
-
* normal params — no type cast required at the call site.
|
|
56
|
+
* The returned client is typed to accept __sessionId, __userId, and __feature
|
|
57
|
+
* alongside the normal params — no type cast required at the call site.
|
|
58
|
+
*
|
|
59
|
+
* For extended thinking models, reasoningTokens is stored as an approximation
|
|
60
|
+
* (thinking block characters ÷ 4). It is informational only — thinking output
|
|
61
|
+
* is already included in outputTokens and is not double-counted in cost.
|
|
50
62
|
*/
|
|
51
63
|
declare function wrapAnthropic<T extends AnthropicLike>(client: T, tracker: Tracker): WrappedAnthropic<T>;
|
|
52
64
|
|
|
@@ -79,6 +91,9 @@ interface GenAILike {
|
|
|
79
91
|
* Wraps a GoogleGenerativeAI client to transparently intercept
|
|
80
92
|
* generateContent / generateContentStream calls and report token usage.
|
|
81
93
|
*
|
|
94
|
+
* Pass __feature in getGenerativeModel params to tag all calls from that model
|
|
95
|
+
* instance with a product feature name (appears in report.byFeature).
|
|
96
|
+
*
|
|
82
97
|
* Returns the same type T that was passed in.
|
|
83
98
|
*/
|
|
84
99
|
declare function wrapGemini<T extends GenAILike>(client: T, tracker: Tracker): T;
|
package/dist/index.js
CHANGED
|
@@ -1379,7 +1379,11 @@ ${issues}`);
|
|
|
1379
1379
|
}
|
|
1380
1380
|
function track(entry) {
|
|
1381
1381
|
const price = resolveModelPrice(entry.model);
|
|
1382
|
-
const costUSD = calculateCost(
|
|
1382
|
+
const costUSD = calculateCost(
|
|
1383
|
+
entry.inputTokens,
|
|
1384
|
+
entry.outputTokens + (entry.reasoningTokens ?? 0),
|
|
1385
|
+
price
|
|
1386
|
+
);
|
|
1383
1387
|
const full = {
|
|
1384
1388
|
...entry,
|
|
1385
1389
|
costUSD,
|
|
@@ -1415,6 +1419,7 @@ ${issues}`);
|
|
|
1415
1419
|
const byModel = {};
|
|
1416
1420
|
const bySession = {};
|
|
1417
1421
|
const byUser = {};
|
|
1422
|
+
const byFeature = {};
|
|
1418
1423
|
let totalInput = 0;
|
|
1419
1424
|
let totalOutput = 0;
|
|
1420
1425
|
let totalCost = 0;
|
|
@@ -1424,11 +1429,12 @@ ${issues}`);
|
|
|
1424
1429
|
totalOutput += e.outputTokens;
|
|
1425
1430
|
totalCost += e.costUSD;
|
|
1426
1431
|
if (e.timestamp > lastTimestamp) lastTimestamp = e.timestamp;
|
|
1427
|
-
const m = byModel[e.model] ??= { costUSD: 0, calls: 0, tokens: { input: 0, output: 0 } };
|
|
1432
|
+
const m = byModel[e.model] ??= { costUSD: 0, calls: 0, tokens: { input: 0, output: 0, reasoning: 0 } };
|
|
1428
1433
|
m.costUSD += e.costUSD;
|
|
1429
1434
|
m.calls += 1;
|
|
1430
1435
|
m.tokens.input += e.inputTokens;
|
|
1431
1436
|
m.tokens.output += e.outputTokens;
|
|
1437
|
+
m.tokens.reasoning += e.reasoningTokens ?? 0;
|
|
1432
1438
|
if (e.sessionId) {
|
|
1433
1439
|
const s = bySession[e.sessionId] ??= { costUSD: 0, calls: 0 };
|
|
1434
1440
|
s.costUSD += e.costUSD;
|
|
@@ -1439,6 +1445,11 @@ ${issues}`);
|
|
|
1439
1445
|
u.costUSD += e.costUSD;
|
|
1440
1446
|
u.calls += 1;
|
|
1441
1447
|
}
|
|
1448
|
+
if (e.feature) {
|
|
1449
|
+
const f = byFeature[e.feature] ??= { costUSD: 0, calls: 0 };
|
|
1450
|
+
f.costUSD += e.costUSD;
|
|
1451
|
+
f.calls += 1;
|
|
1452
|
+
}
|
|
1442
1453
|
}
|
|
1443
1454
|
return {
|
|
1444
1455
|
totalCostUSD: totalCost,
|
|
@@ -1446,6 +1457,7 @@ ${issues}`);
|
|
|
1446
1457
|
byModel,
|
|
1447
1458
|
bySession,
|
|
1448
1459
|
byUser,
|
|
1460
|
+
byFeature,
|
|
1449
1461
|
period: { from: startedAt, to: lastTimestamp }
|
|
1450
1462
|
};
|
|
1451
1463
|
}
|
|
@@ -1461,16 +1473,18 @@ ${issues}`);
|
|
|
1461
1473
|
}
|
|
1462
1474
|
async function exportCSV() {
|
|
1463
1475
|
const entries = await Promise.resolve(storage.getAll());
|
|
1464
|
-
const header = "timestamp,model,inputTokens,outputTokens,costUSD,sessionId,userId";
|
|
1476
|
+
const header = "timestamp,model,inputTokens,outputTokens,reasoningTokens,costUSD,sessionId,userId,feature";
|
|
1465
1477
|
const rows = entries.map(
|
|
1466
1478
|
(e) => [
|
|
1467
1479
|
csvEscape(e.timestamp),
|
|
1468
1480
|
csvEscape(e.model),
|
|
1469
1481
|
e.inputTokens,
|
|
1470
1482
|
e.outputTokens,
|
|
1483
|
+
e.reasoningTokens ?? 0,
|
|
1471
1484
|
e.costUSD.toFixed(8),
|
|
1472
1485
|
csvEscape(e.sessionId ?? ""),
|
|
1473
|
-
csvEscape(e.userId ?? "")
|
|
1486
|
+
csvEscape(e.userId ?? ""),
|
|
1487
|
+
csvEscape(e.feature ?? "")
|
|
1474
1488
|
].join(",")
|
|
1475
1489
|
);
|
|
1476
1490
|
return [header, ...rows].join("\n");
|
|
@@ -1496,42 +1510,46 @@ function csvEscape(value) {
|
|
|
1496
1510
|
|
|
1497
1511
|
// src/providers/openai.ts
|
|
1498
1512
|
function extractMeta(params) {
|
|
1499
|
-
const { __sessionId, __userId, ...cleaned } = params;
|
|
1513
|
+
const { __sessionId, __userId, __feature, ...cleaned } = params;
|
|
1500
1514
|
return {
|
|
1501
1515
|
cleaned,
|
|
1502
1516
|
sessionId: typeof __sessionId === "string" ? __sessionId : void 0,
|
|
1503
|
-
userId: typeof __userId === "string" ? __userId : void 0
|
|
1517
|
+
userId: typeof __userId === "string" ? __userId : void 0,
|
|
1518
|
+
feature: typeof __feature === "string" ? __feature : void 0
|
|
1504
1519
|
};
|
|
1505
1520
|
}
|
|
1506
1521
|
function extractUsage(usage) {
|
|
1507
|
-
if (!usage) return { inputTokens: 0, outputTokens: 0 };
|
|
1522
|
+
if (!usage) return { inputTokens: 0, outputTokens: 0, reasoningTokens: 0 };
|
|
1508
1523
|
return {
|
|
1509
1524
|
inputTokens: usage.prompt_tokens ?? usage.input_tokens ?? 0,
|
|
1510
|
-
outputTokens: usage.completion_tokens ?? usage.output_tokens ?? 0
|
|
1525
|
+
outputTokens: usage.completion_tokens ?? usage.output_tokens ?? 0,
|
|
1526
|
+
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0
|
|
1511
1527
|
};
|
|
1512
1528
|
}
|
|
1513
|
-
function trackWithMeta(tracker, model, inputTokens, outputTokens, sessionId, userId) {
|
|
1529
|
+
function trackWithMeta(tracker, model, inputTokens, outputTokens, reasoningTokens, sessionId, userId, feature) {
|
|
1514
1530
|
tracker.track({
|
|
1515
1531
|
model,
|
|
1516
1532
|
inputTokens,
|
|
1517
1533
|
outputTokens,
|
|
1534
|
+
...reasoningTokens > 0 && { reasoningTokens },
|
|
1518
1535
|
...sessionId !== void 0 && { sessionId },
|
|
1519
|
-
...userId !== void 0 && { userId }
|
|
1536
|
+
...userId !== void 0 && { userId },
|
|
1537
|
+
...feature !== void 0 && { feature }
|
|
1520
1538
|
});
|
|
1521
1539
|
}
|
|
1522
|
-
async function* wrapStream(stream, model, sessionId, userId, tracker) {
|
|
1540
|
+
async function* wrapStream(stream, model, sessionId, userId, feature, tracker) {
|
|
1523
1541
|
let lastChunk;
|
|
1524
1542
|
for await (const chunk of stream) {
|
|
1525
1543
|
lastChunk = chunk;
|
|
1526
1544
|
yield chunk;
|
|
1527
1545
|
}
|
|
1528
|
-
const { inputTokens, outputTokens } = extractUsage(lastChunk?.usage);
|
|
1546
|
+
const { inputTokens, outputTokens, reasoningTokens } = extractUsage(lastChunk?.usage);
|
|
1529
1547
|
if (!lastChunk?.usage) {
|
|
1530
1548
|
console.warn(
|
|
1531
1549
|
`[tokenwatch] No usage data in stream for model "${model}". Cost recorded as $0. Pass stream_options: { include_usage: true } to get accurate costs.`
|
|
1532
1550
|
);
|
|
1533
1551
|
}
|
|
1534
|
-
trackWithMeta(tracker, model, inputTokens, outputTokens, sessionId, userId);
|
|
1552
|
+
trackWithMeta(tracker, model, inputTokens, outputTokens, reasoningTokens, sessionId, userId, feature);
|
|
1535
1553
|
}
|
|
1536
1554
|
function wrapOpenAI(client, tracker) {
|
|
1537
1555
|
const proxiedCompletions = new Proxy(client.chat.completions, {
|
|
@@ -1539,7 +1557,7 @@ function wrapOpenAI(client, tracker) {
|
|
|
1539
1557
|
if (prop !== "create")
|
|
1540
1558
|
return target[prop];
|
|
1541
1559
|
return async function(params) {
|
|
1542
|
-
const { cleaned, sessionId, userId } = extractMeta(params);
|
|
1560
|
+
const { cleaned, sessionId, userId, feature } = extractMeta(params);
|
|
1543
1561
|
const model = typeof cleaned["model"] === "string" ? cleaned["model"] : "unknown";
|
|
1544
1562
|
const result = await target.create(cleaned);
|
|
1545
1563
|
if (result && typeof result === "object" && Symbol.asyncIterator in result) {
|
|
@@ -1548,18 +1566,21 @@ function wrapOpenAI(client, tracker) {
|
|
|
1548
1566
|
model,
|
|
1549
1567
|
sessionId,
|
|
1550
1568
|
userId,
|
|
1569
|
+
feature,
|
|
1551
1570
|
tracker
|
|
1552
1571
|
);
|
|
1553
1572
|
}
|
|
1554
1573
|
const completion = result;
|
|
1555
|
-
const { inputTokens, outputTokens } = extractUsage(completion.usage);
|
|
1574
|
+
const { inputTokens, outputTokens, reasoningTokens } = extractUsage(completion.usage);
|
|
1556
1575
|
trackWithMeta(
|
|
1557
1576
|
tracker,
|
|
1558
1577
|
completion.model ?? model,
|
|
1559
1578
|
inputTokens,
|
|
1560
1579
|
outputTokens,
|
|
1580
|
+
reasoningTokens,
|
|
1561
1581
|
sessionId,
|
|
1562
|
-
userId
|
|
1582
|
+
userId,
|
|
1583
|
+
feature
|
|
1563
1584
|
);
|
|
1564
1585
|
return result;
|
|
1565
1586
|
};
|
|
@@ -1571,9 +1592,25 @@ function wrapOpenAI(client, tracker) {
|
|
|
1571
1592
|
return target[prop];
|
|
1572
1593
|
}
|
|
1573
1594
|
});
|
|
1595
|
+
const proxiedEmbeddings = client.embeddings ? new Proxy(client.embeddings, {
|
|
1596
|
+
get(target, prop) {
|
|
1597
|
+
if (prop !== "create")
|
|
1598
|
+
return target[prop];
|
|
1599
|
+
return async function(params) {
|
|
1600
|
+
const { cleaned, sessionId, userId, feature } = extractMeta(params);
|
|
1601
|
+
const model = typeof cleaned["model"] === "string" ? cleaned["model"] : "unknown";
|
|
1602
|
+
const result = await target.create(cleaned);
|
|
1603
|
+
const embedding = result;
|
|
1604
|
+
const inputTokens = embedding.usage?.total_tokens ?? 0;
|
|
1605
|
+
trackWithMeta(tracker, embedding.model ?? model, inputTokens, 0, 0, sessionId, userId, feature);
|
|
1606
|
+
return result;
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
}) : void 0;
|
|
1574
1610
|
return new Proxy(client, {
|
|
1575
1611
|
get(target, prop) {
|
|
1576
1612
|
if (prop === "chat") return proxiedChat;
|
|
1613
|
+
if (prop === "embeddings") return proxiedEmbeddings;
|
|
1577
1614
|
return target[prop];
|
|
1578
1615
|
}
|
|
1579
1616
|
});
|
|
@@ -1581,11 +1618,12 @@ function wrapOpenAI(client, tracker) {
|
|
|
1581
1618
|
|
|
1582
1619
|
// src/providers/anthropic.ts
|
|
1583
1620
|
function extractMeta2(params) {
|
|
1584
|
-
const { __sessionId, __userId, ...cleaned } = params;
|
|
1621
|
+
const { __sessionId, __userId, __feature, ...cleaned } = params;
|
|
1585
1622
|
return {
|
|
1586
1623
|
cleaned,
|
|
1587
1624
|
sessionId: typeof __sessionId === "string" ? __sessionId : void 0,
|
|
1588
|
-
userId: typeof __userId === "string" ? __userId : void 0
|
|
1625
|
+
userId: typeof __userId === "string" ? __userId : void 0,
|
|
1626
|
+
feature: typeof __feature === "string" ? __feature : void 0
|
|
1589
1627
|
};
|
|
1590
1628
|
}
|
|
1591
1629
|
function extractUsage2(usage) {
|
|
@@ -1595,18 +1633,31 @@ function extractUsage2(usage) {
|
|
|
1595
1633
|
outputTokens: usage.output_tokens ?? 0
|
|
1596
1634
|
};
|
|
1597
1635
|
}
|
|
1598
|
-
function
|
|
1636
|
+
function extractThinkingTokenApprox(content) {
|
|
1637
|
+
if (!content) return 0;
|
|
1638
|
+
const chars = content.filter((b) => b.type === "thinking").reduce((sum, b) => sum + (b.thinking?.length ?? 0), 0);
|
|
1639
|
+
return chars > 0 ? Math.round(chars / 4) : 0;
|
|
1640
|
+
}
|
|
1641
|
+
function trackWithMeta2(tracker, model, inputTokens, outputTokens, reasoningTokens, sessionId, userId, feature) {
|
|
1599
1642
|
tracker.track({
|
|
1600
1643
|
model,
|
|
1601
1644
|
inputTokens,
|
|
1602
1645
|
outputTokens,
|
|
1646
|
+
// For Anthropic, reasoningTokens is informational (thinking already in outputTokens).
|
|
1647
|
+
// Pass 0 so tracker does not add it to cost (tracker only adds when > 0 AND separate).
|
|
1648
|
+
// We store it as a field but the tracker cost formula adds reasoningTokens to outputTokens,
|
|
1649
|
+
// so we must NOT pass it here to avoid double-counting.
|
|
1603
1650
|
...sessionId !== void 0 && { sessionId },
|
|
1604
|
-
...userId !== void 0 && { userId }
|
|
1651
|
+
...userId !== void 0 && { userId },
|
|
1652
|
+
...feature !== void 0 && { feature },
|
|
1653
|
+
...reasoningTokens > 0 && { reasoningTokens }
|
|
1605
1654
|
});
|
|
1606
1655
|
}
|
|
1607
|
-
async function* wrapStream2(stream, model, sessionId, userId, tracker) {
|
|
1656
|
+
async function* wrapStream2(stream, model, sessionId, userId, feature, tracker) {
|
|
1608
1657
|
let inputTokens = 0;
|
|
1609
1658
|
let outputTokens = 0;
|
|
1659
|
+
let currentBlockIsThinking = false;
|
|
1660
|
+
let thinkingCharCount = 0;
|
|
1610
1661
|
for await (const event of stream) {
|
|
1611
1662
|
yield event;
|
|
1612
1663
|
if (event.type === "message_start" && event.message?.usage) {
|
|
@@ -1615,8 +1666,18 @@ async function* wrapStream2(stream, model, sessionId, userId, tracker) {
|
|
|
1615
1666
|
if (event.type === "message_delta" && event.usage) {
|
|
1616
1667
|
outputTokens = event.usage.output_tokens ?? 0;
|
|
1617
1668
|
}
|
|
1669
|
+
if (event.type === "content_block_start") {
|
|
1670
|
+
currentBlockIsThinking = event.content_block?.type === "thinking";
|
|
1671
|
+
}
|
|
1672
|
+
if (event.type === "content_block_stop") {
|
|
1673
|
+
currentBlockIsThinking = false;
|
|
1674
|
+
}
|
|
1675
|
+
if (event.type === "content_block_delta" && currentBlockIsThinking && event.delta?.thinking) {
|
|
1676
|
+
thinkingCharCount += event.delta.thinking.length;
|
|
1677
|
+
}
|
|
1618
1678
|
}
|
|
1619
|
-
|
|
1679
|
+
const reasoningTokens = thinkingCharCount > 0 ? Math.round(thinkingCharCount / 4) : 0;
|
|
1680
|
+
trackWithMeta2(tracker, model, inputTokens, outputTokens, reasoningTokens, sessionId, userId, feature);
|
|
1620
1681
|
}
|
|
1621
1682
|
function wrapAnthropic(client, tracker) {
|
|
1622
1683
|
const proxiedMessages = new Proxy(client.messages, {
|
|
@@ -1624,7 +1685,7 @@ function wrapAnthropic(client, tracker) {
|
|
|
1624
1685
|
if (prop !== "create")
|
|
1625
1686
|
return target[prop];
|
|
1626
1687
|
return async function(params) {
|
|
1627
|
-
const { cleaned, sessionId, userId } = extractMeta2(params);
|
|
1688
|
+
const { cleaned, sessionId, userId, feature } = extractMeta2(params);
|
|
1628
1689
|
const model = typeof cleaned["model"] === "string" ? cleaned["model"] : "unknown";
|
|
1629
1690
|
const result = await target.create(cleaned);
|
|
1630
1691
|
if (result && typeof result === "object" && Symbol.asyncIterator in result) {
|
|
@@ -1633,18 +1694,22 @@ function wrapAnthropic(client, tracker) {
|
|
|
1633
1694
|
model,
|
|
1634
1695
|
sessionId,
|
|
1635
1696
|
userId,
|
|
1697
|
+
feature,
|
|
1636
1698
|
tracker
|
|
1637
1699
|
);
|
|
1638
1700
|
}
|
|
1639
1701
|
const message = result;
|
|
1640
1702
|
const { inputTokens, outputTokens } = extractUsage2(message.usage);
|
|
1703
|
+
const reasoningTokens = extractThinkingTokenApprox(message.content);
|
|
1641
1704
|
trackWithMeta2(
|
|
1642
1705
|
tracker,
|
|
1643
1706
|
message.model ?? model,
|
|
1644
1707
|
inputTokens,
|
|
1645
1708
|
outputTokens,
|
|
1709
|
+
reasoningTokens,
|
|
1646
1710
|
sessionId,
|
|
1647
|
-
userId
|
|
1711
|
+
userId,
|
|
1712
|
+
feature
|
|
1648
1713
|
);
|
|
1649
1714
|
return result;
|
|
1650
1715
|
};
|
|
@@ -1665,7 +1730,11 @@ function wrapGemini(client, tracker) {
|
|
|
1665
1730
|
if (prop !== "getGenerativeModel")
|
|
1666
1731
|
return target[prop];
|
|
1667
1732
|
return function(modelParams) {
|
|
1668
|
-
const
|
|
1733
|
+
const { __sessionId, __userId, __feature, ...cleanedParams } = modelParams;
|
|
1734
|
+
const feature = typeof __feature === "string" ? __feature : void 0;
|
|
1735
|
+
const sessionId = typeof __sessionId === "string" ? __sessionId : void 0;
|
|
1736
|
+
const userId = typeof __userId === "string" ? __userId : void 0;
|
|
1737
|
+
const modelInstance = target.getGenerativeModel(cleanedParams);
|
|
1669
1738
|
const modelId = modelParams.model;
|
|
1670
1739
|
return new Proxy(modelInstance, {
|
|
1671
1740
|
get(mTarget, mProp) {
|
|
@@ -1676,7 +1745,10 @@ function wrapGemini(client, tracker) {
|
|
|
1676
1745
|
tracker.track({
|
|
1677
1746
|
model: modelId,
|
|
1678
1747
|
inputTokens: meta?.promptTokenCount ?? 0,
|
|
1679
|
-
outputTokens: meta?.candidatesTokenCount ?? 0
|
|
1748
|
+
outputTokens: meta?.candidatesTokenCount ?? 0,
|
|
1749
|
+
...sessionId !== void 0 && { sessionId },
|
|
1750
|
+
...userId !== void 0 && { userId },
|
|
1751
|
+
...feature !== void 0 && { feature }
|
|
1680
1752
|
});
|
|
1681
1753
|
return result;
|
|
1682
1754
|
};
|
|
@@ -1689,7 +1761,10 @@ function wrapGemini(client, tracker) {
|
|
|
1689
1761
|
tracker.track({
|
|
1690
1762
|
model: modelId,
|
|
1691
1763
|
inputTokens: meta?.promptTokenCount ?? 0,
|
|
1692
|
-
outputTokens: meta?.candidatesTokenCount ?? 0
|
|
1764
|
+
outputTokens: meta?.candidatesTokenCount ?? 0,
|
|
1765
|
+
...sessionId !== void 0 && { sessionId },
|
|
1766
|
+
...userId !== void 0 && { userId },
|
|
1767
|
+
...feature !== void 0 && { feature }
|
|
1693
1768
|
});
|
|
1694
1769
|
}).catch(() => {
|
|
1695
1770
|
});
|