@tangle-network/sdk-telemetry 0.60.78-develop.20261025200559.0984d38 → 0.60.78-develop.20261025204117.3cefa34

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.mjs CHANGED
@@ -1,206 +1,6 @@
1
1
  import { c as parseServerTiming } from "./server-timing-CTGu_pos.mjs";
2
2
  import { ORCHESTRATOR_HOP_ID_HEADER, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SpanRecorder, isAdoptablePtid, mintPtid, monotonicNs, readOrMintPtid, spanDurationMs } from "./stage-span.mjs";
3
3
  import { GEN_AI_CONVERSATION_ID, GEN_AI_CONVERSATION_ID as GEN_AI_CONVERSATION_ID$1, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OPERATION_NAME as GEN_AI_OPERATION_NAME$1, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_REQUEST_MODEL as GEN_AI_REQUEST_MODEL$1, GEN_AI_RESPONSE_MODEL, GEN_AI_RESPONSE_MODEL as GEN_AI_RESPONSE_MODEL$1, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_INPUT_TOKENS as GEN_AI_USAGE_INPUT_TOKENS$1, GEN_AI_USAGE_OUTPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS as GEN_AI_USAGE_OUTPUT_TOKENS$1, SSEChunkParser, StreamUsageExtractor, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, addTokenUsage, consumeSSEStream, createStreamUsageExtractor, createUsageCallback, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, isFilePart, isReasoningPart, isTextPart, isToolPart, parseSSEData as parseSSEData$1, parseSSEStream, readTokenCostUsd, readTokenUsage, tokenCount, tokenUsageSource } from "@tangle-network/agent-core";
4
- //#region src/credits.ts
5
- const DEFAULT_CONFIG$2 = {
6
- refreshIntervalMs: 6e4,
7
- warningThreshold: .2,
8
- criticalThreshold: .05
9
- };
10
- var CreditTracker = class {
11
- config;
12
- provider;
13
- storage;
14
- cachedBalance;
15
- lastRefresh;
16
- refreshTimer;
17
- reservations = /* @__PURE__ */ new Map();
18
- constructor(config, provider, storage) {
19
- this.config = {
20
- ...DEFAULT_CONFIG$2,
21
- ...config
22
- };
23
- this.provider = provider;
24
- this.storage = storage;
25
- if (this.config.refreshIntervalMs > 0) this.startRefreshTimer();
26
- }
27
- async getBalance(forceRefresh = false) {
28
- if (forceRefresh || !this.cachedBalance || this.isStale()) {
29
- this.cachedBalance = await this.provider.getBalance();
30
- this.lastRefresh = /* @__PURE__ */ new Date();
31
- this.checkThresholds(this.cachedBalance);
32
- if (this.storage) await this.storage.set(`credits:${this.config.projectRef}:balance`, this.cachedBalance);
33
- this.config.onBalanceUpdate?.(this.cachedBalance);
34
- }
35
- return this.cachedBalance;
36
- }
37
- async getTransactions(options) {
38
- return this.provider.getTransactions(options);
39
- }
40
- async hasCredits(amount) {
41
- const balance = await this.getBalance();
42
- const reservedTotal = this.getReservedTotal();
43
- return balance.available - reservedTotal >= amount;
44
- }
45
- async reserve(amount, options) {
46
- if (!await this.hasCredits(amount)) return null;
47
- const reservationId = await this.provider.reserveCredit(amount);
48
- if (!reservationId) return null;
49
- const now = /* @__PURE__ */ new Date();
50
- this.reservations.set(reservationId, {
51
- amount,
52
- createdAt: now,
53
- expiresAt: options?.ttlMs ? new Date(now.getTime() + options.ttlMs) : void 0
54
- });
55
- return reservationId;
56
- }
57
- async release(reservationId) {
58
- await this.provider.releaseReservation(reservationId);
59
- this.reservations.delete(reservationId);
60
- }
61
- async charge(reservationId, actualAmount) {
62
- const transaction = await this.provider.chargeReservation(reservationId, actualAmount);
63
- this.reservations.delete(reservationId);
64
- await this.getBalance(true);
65
- return transaction;
66
- }
67
- async chargeImmediate(amount, _description) {
68
- const reservationId = await this.reserve(amount);
69
- if (!reservationId) return null;
70
- return this.charge(reservationId, amount);
71
- }
72
- getReservedTotal() {
73
- this.cleanupExpiredReservations();
74
- let total = 0;
75
- for (const reservation of this.reservations.values()) total += reservation.amount;
76
- return total;
77
- }
78
- getEffectiveBalance() {
79
- const balance = this.cachedBalance;
80
- if (!balance) return 0;
81
- return balance.available - this.getReservedTotal();
82
- }
83
- getUsagePercent() {
84
- const balance = this.cachedBalance;
85
- if (!balance || balance.limit === 0) return 0;
86
- return balance.used / balance.limit * 100;
87
- }
88
- getRemainingPercent() {
89
- const balance = this.cachedBalance;
90
- if (!balance || balance.limit === 0) return 100;
91
- return balance.available / balance.limit * 100;
92
- }
93
- isLow() {
94
- return this.getRemainingPercent() / 100 <= this.config.warningThreshold;
95
- }
96
- isCritical() {
97
- return this.getRemainingPercent() / 100 <= this.config.criticalThreshold;
98
- }
99
- async close() {
100
- this.stopRefreshTimer();
101
- for (const [id] of this.reservations) try {
102
- await this.release(id);
103
- } catch {}
104
- }
105
- isStale() {
106
- if (!this.lastRefresh) return true;
107
- return Date.now() - this.lastRefresh.getTime() > this.config.refreshIntervalMs;
108
- }
109
- checkThresholds(balance) {
110
- if (!balance.limit || balance.limit <= 0) return;
111
- const remainingPercent = balance.available / balance.limit;
112
- if (remainingPercent <= this.config.criticalThreshold) this.config.onCriticalBalance?.(balance);
113
- else if (remainingPercent <= this.config.warningThreshold) this.config.onLowBalance?.(balance);
114
- }
115
- cleanupExpiredReservations() {
116
- const now = Date.now();
117
- for (const [id, reservation] of this.reservations) if (reservation.expiresAt && reservation.expiresAt.getTime() < now) this.reservations.delete(id);
118
- }
119
- startRefreshTimer() {
120
- if (this.refreshTimer) return;
121
- this.refreshTimer = setInterval(() => this.getBalance(true), this.config.refreshIntervalMs);
122
- }
123
- stopRefreshTimer() {
124
- if (this.refreshTimer) {
125
- clearInterval(this.refreshTimer);
126
- this.refreshTimer = void 0;
127
- }
128
- }
129
- };
130
- var MemoryCreditProvider = class {
131
- balance;
132
- transactions = [];
133
- reservations = /* @__PURE__ */ new Map();
134
- constructor(initialBalance = {}) {
135
- this.balance = {
136
- available: initialBalance.available ?? 1e3,
137
- used: initialBalance.used ?? 0,
138
- limit: initialBalance.limit ?? 1e3,
139
- currency: initialBalance.currency ?? "credits"
140
- };
141
- }
142
- async getBalance() {
143
- return { ...this.balance };
144
- }
145
- async getTransactions(options) {
146
- let result = [...this.transactions];
147
- if (options?.since) {
148
- const since = options.since;
149
- result = result.filter((t) => t.timestamp >= since);
150
- }
151
- result = result.slice(options?.offset ?? 0, (options?.offset ?? 0) + (options?.limit ?? 100));
152
- return result;
153
- }
154
- async checkCredit(amount) {
155
- const reservedTotal = Array.from(this.reservations.values()).reduce((sum, amt) => sum + amt, 0);
156
- return this.balance.available - reservedTotal >= amount;
157
- }
158
- async reserveCredit(amount) {
159
- if (!await this.checkCredit(amount)) return null;
160
- const id = `res-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
161
- this.reservations.set(id, amount);
162
- return id;
163
- }
164
- async releaseReservation(reservationId) {
165
- this.reservations.delete(reservationId);
166
- }
167
- async chargeReservation(reservationId, actualAmount) {
168
- const reserved = this.reservations.get(reservationId);
169
- if (reserved === void 0) throw new Error(`Reservation not found: ${reservationId}`);
170
- const chargeAmount = actualAmount ?? reserved;
171
- this.reservations.delete(reservationId);
172
- this.balance.available -= chargeAmount;
173
- this.balance.used += chargeAmount;
174
- const transaction = {
175
- id: `txn-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
176
- type: "charge",
177
- amount: chargeAmount,
178
- balance: this.balance.available,
179
- description: `Charged from reservation ${reservationId}`,
180
- timestamp: /* @__PURE__ */ new Date()
181
- };
182
- this.transactions.unshift(transaction);
183
- return transaction;
184
- }
185
- addCredits(amount, description) {
186
- this.balance.available += amount;
187
- this.balance.limit += amount;
188
- const transaction = {
189
- id: `txn-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
190
- type: "grant",
191
- amount,
192
- balance: this.balance.available,
193
- description,
194
- timestamp: /* @__PURE__ */ new Date()
195
- };
196
- this.transactions.unshift(transaction);
197
- return transaction;
198
- }
199
- };
200
- function createCreditTracker(config, provider, storage) {
201
- return new CreditTracker(config, provider, storage);
202
- }
203
- //#endregion
204
4
  //#region src/enrichment/parse.ts
205
5
  const VALID_PRODUCTS = [
206
6
  "vibe_coding",
@@ -1595,521 +1395,6 @@ function createTraceCollector(config) {
1595
1395
  return new TraceCollector(config);
1596
1396
  }
1597
1397
  //#endregion
1598
- //#region src/tracker.ts
1599
- const DEFAULT_CONFIG$1 = {
1600
- enabled: true,
1601
- flushIntervalMs: 3e4,
1602
- maxBatchSize: 100,
1603
- maxQueueSize: 1e3,
1604
- sampleRate: 1,
1605
- excludePatterns: [],
1606
- includeMetadata: true,
1607
- persistOffline: true
1608
- };
1609
- var TelemetryTracker = class {
1610
- config;
1611
- sinks = [];
1612
- queue = [];
1613
- storage;
1614
- sequence = 0;
1615
- flushTimer;
1616
- sessionStartTime;
1617
- isFlushing = false;
1618
- constructor(config, storage) {
1619
- this.config = {
1620
- ...DEFAULT_CONFIG$1,
1621
- ...config
1622
- };
1623
- this.storage = storage;
1624
- if (this.config.enabled && this.config.flushIntervalMs > 0) this.startFlushTimer();
1625
- }
1626
- addSink(sink) {
1627
- this.sinks.push(sink);
1628
- return this;
1629
- }
1630
- removeSink(name) {
1631
- const index = this.sinks.findIndex((s) => s.name === name);
1632
- if (index !== -1) this.sinks.splice(index, 1);
1633
- return this;
1634
- }
1635
- startSession(metadata) {
1636
- const sessionId = this.config.sessionId ?? `session-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
1637
- this.sessionStartTime = /* @__PURE__ */ new Date();
1638
- this.track("session_start", "session.started", {
1639
- ...metadata,
1640
- sessionId,
1641
- startTime: this.sessionStartTime.toISOString()
1642
- });
1643
- return sessionId;
1644
- }
1645
- endSession(metadata) {
1646
- const duration = this.sessionStartTime ? Date.now() - this.sessionStartTime.getTime() : 0;
1647
- this.track("session_end", "session.ended", {
1648
- ...metadata,
1649
- durationMs: duration,
1650
- eventCount: this.sequence
1651
- });
1652
- this.flush();
1653
- }
1654
- track(type, name, data = {}) {
1655
- if (!this.config.enabled) return;
1656
- if (!this.shouldSample()) return;
1657
- if (this.isExcluded(name)) return;
1658
- const event = {
1659
- id: `evt-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
1660
- type,
1661
- name,
1662
- projectRef: this.config.projectRef,
1663
- sessionId: this.config.sessionId,
1664
- userId: this.config.userId,
1665
- data: this.config.includeMetadata ? this.enrichData(data) : data,
1666
- timestamp: /* @__PURE__ */ new Date(),
1667
- sequence: ++this.sequence
1668
- };
1669
- this.enqueue(event);
1670
- }
1671
- trackPerformance(metric) {
1672
- this.track("performance", `perf.${metric.name}`, {
1673
- value: metric.value,
1674
- unit: metric.unit,
1675
- tags: metric.tags
1676
- });
1677
- }
1678
- trackError(error, context) {
1679
- const errorData = error instanceof Error ? {
1680
- message: error.message,
1681
- name: error.name,
1682
- stack: error.stack
1683
- } : { message: error };
1684
- this.track("error", "error.occurred", {
1685
- ...errorData,
1686
- ...context
1687
- });
1688
- }
1689
- trackApiRequest(method, path, status, durationMs, metadata) {
1690
- this.track("api_request", `api.${method.toLowerCase()}.${path}`, {
1691
- method,
1692
- path,
1693
- status,
1694
- durationMs,
1695
- ...metadata
1696
- });
1697
- }
1698
- trackAgentExecution(identifier, executionId, durationMs, success, metadata) {
1699
- this.track("agent_execution", `agent.${identifier}`, {
1700
- identifier,
1701
- executionId,
1702
- durationMs,
1703
- success,
1704
- ...metadata
1705
- });
1706
- }
1707
- async flush() {
1708
- if (this.isFlushing || this.queue.length === 0) return;
1709
- this.isFlushing = true;
1710
- try {
1711
- const events = this.queue.splice(0, this.config.maxBatchSize);
1712
- await Promise.all(this.sinks.map((sink) => sink.send(events)));
1713
- if (this.config.persistOffline && this.storage) await this.clearPersistedEvents(events.map((e) => e.id));
1714
- } catch (_error) {
1715
- if (this.config.persistOffline && this.storage) await this.persistEvents(this.queue);
1716
- } finally {
1717
- this.isFlushing = false;
1718
- }
1719
- }
1720
- async close() {
1721
- this.stopFlushTimer();
1722
- await this.flush();
1723
- await Promise.all(this.sinks.map((sink) => sink.close()));
1724
- }
1725
- getQueueSize() {
1726
- return this.queue.length;
1727
- }
1728
- isEnabled() {
1729
- return this.config.enabled;
1730
- }
1731
- enable() {
1732
- this.config.enabled = true;
1733
- this.startFlushTimer();
1734
- }
1735
- disable() {
1736
- this.config.enabled = false;
1737
- this.stopFlushTimer();
1738
- }
1739
- enqueue(event) {
1740
- if (this.queue.length >= this.config.maxQueueSize) this.queue.shift();
1741
- this.queue.push(event);
1742
- if (this.queue.length >= this.config.maxBatchSize) this.flush();
1743
- if (this.config.persistOffline && this.storage) this.persistEvent(event);
1744
- }
1745
- shouldSample() {
1746
- return Math.random() < this.config.sampleRate;
1747
- }
1748
- isExcluded(name) {
1749
- return this.config.excludePatterns.some((pattern) => {
1750
- if (pattern.includes("*")) return new RegExp(`^${pattern.replace(/\*/g, ".*").replace(/\?/g, ".")}$`).test(name);
1751
- return name === pattern;
1752
- });
1753
- }
1754
- enrichData(data) {
1755
- return {
1756
- ...data,
1757
- _meta: {
1758
- timestamp: Date.now(),
1759
- platform: typeof navigator !== "undefined" ? navigator.userAgent : "node",
1760
- timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
1761
- }
1762
- };
1763
- }
1764
- startFlushTimer() {
1765
- if (this.flushTimer) return;
1766
- this.flushTimer = setInterval(() => this.flush(), this.config.flushIntervalMs);
1767
- }
1768
- stopFlushTimer() {
1769
- if (this.flushTimer) {
1770
- clearInterval(this.flushTimer);
1771
- this.flushTimer = void 0;
1772
- }
1773
- }
1774
- async persistEvent(event) {
1775
- if (!this.storage) return;
1776
- const key = `telemetry:${event.id}`;
1777
- await this.storage.set(key, event);
1778
- }
1779
- async persistEvents(events) {
1780
- if (!this.storage) return;
1781
- await Promise.all(events.map((e) => this.persistEvent(e)));
1782
- }
1783
- async clearPersistedEvents(ids) {
1784
- if (!this.storage) return;
1785
- await Promise.all(ids.map((id) => this.storage?.delete(`telemetry:${id}`)));
1786
- }
1787
- async loadPersistedEvents() {
1788
- if (!this.storage) return [];
1789
- const telemetryKeys = (await this.storage.keys()).filter((k) => k.startsWith("telemetry:"));
1790
- const events = [];
1791
- for (const key of telemetryKeys) {
1792
- const event = await this.storage.get(key);
1793
- if (event) events.push(event);
1794
- }
1795
- return events.sort((a, b) => a.sequence - b.sequence);
1796
- }
1797
- };
1798
- function createTelemetryTracker(config, storage) {
1799
- return new TelemetryTracker(config, storage);
1800
- }
1801
- //#endregion
1802
- //#region src/usage.ts
1803
- const DEFAULT_CONFIG = {
1804
- autoTrack: true,
1805
- trackApiCalls: true,
1806
- trackAgentExecutions: true,
1807
- trackErrors: true,
1808
- batchSize: 50,
1809
- flushIntervalMs: 3e4
1810
- };
1811
- const OPERATION_COSTS = {
1812
- "api.get": .001,
1813
- "api.post": .002,
1814
- "api.put": .002,
1815
- "api.delete": .001,
1816
- "agent.execution": .01,
1817
- "agent.streaming": .015,
1818
- "token.input": 1e-5,
1819
- "token.output": 3e-5,
1820
- default: .001
1821
- };
1822
- var UsageTracker = class {
1823
- config;
1824
- provider;
1825
- storage;
1826
- queue = [];
1827
- flushTimer;
1828
- isFlushing = false;
1829
- sessionMetrics = {
1830
- totalCredits: 0,
1831
- totalOperations: 0,
1832
- totalDurationMs: 0,
1833
- totalInputTokens: 0,
1834
- totalOutputTokens: 0,
1835
- operationCounts: /* @__PURE__ */ new Map(),
1836
- startTime: Date.now()
1837
- };
1838
- constructor(config, provider, storage) {
1839
- this.config = {
1840
- ...DEFAULT_CONFIG,
1841
- ...config
1842
- };
1843
- this.provider = provider;
1844
- this.storage = storage;
1845
- if (this.config.flushIntervalMs > 0) this.startFlushTimer();
1846
- }
1847
- recordApiCall(metric) {
1848
- if (!this.config.trackApiCalls) return;
1849
- const operation = `api.${metric.method.toLowerCase()}`;
1850
- const credits = this.calculateCost(operation, {
1851
- durationMs: metric.durationMs,
1852
- requestSize: metric.requestSize,
1853
- responseSize: metric.responseSize
1854
- });
1855
- this.record({
1856
- projectRef: this.config.projectRef,
1857
- userId: this.config.userId,
1858
- operation,
1859
- credits,
1860
- durationMs: metric.durationMs,
1861
- metadata: {
1862
- path: metric.path,
1863
- status: metric.status,
1864
- requestSize: metric.requestSize,
1865
- responseSize: metric.responseSize,
1866
- error: metric.error
1867
- }
1868
- });
1869
- }
1870
- recordAgentExecution(metric) {
1871
- if (!this.config.trackAgentExecutions) return;
1872
- const operation = "agent.execution";
1873
- const tokenCost = (metric.inputTokens ?? 0) * OPERATION_COSTS["token.input"] + (metric.outputTokens ?? 0) * OPERATION_COSTS["token.output"];
1874
- const credits = this.calculateCost(operation, { durationMs: metric.durationMs }) + tokenCost;
1875
- this.record({
1876
- projectRef: metric.projectRef,
1877
- userId: this.config.userId,
1878
- operation,
1879
- credits,
1880
- durationMs: metric.durationMs,
1881
- inputTokens: metric.inputTokens,
1882
- outputTokens: metric.outputTokens,
1883
- metadata: {
1884
- identifier: metric.identifier,
1885
- executionId: metric.executionId,
1886
- toolCalls: metric.toolCalls,
1887
- success: metric.success,
1888
- error: metric.error
1889
- }
1890
- });
1891
- }
1892
- recordError(error, operation) {
1893
- if (!this.config.trackErrors) return;
1894
- this.record({
1895
- projectRef: this.config.projectRef,
1896
- userId: this.config.userId,
1897
- operation: `error.${operation}`,
1898
- credits: 0,
1899
- metadata: {
1900
- error: error instanceof Error ? error.message : error,
1901
- stack: error instanceof Error ? error.stack : void 0
1902
- }
1903
- });
1904
- }
1905
- record(usage) {
1906
- this.queue.push(usage);
1907
- this.sessionMetrics.totalCredits += usage.credits;
1908
- this.sessionMetrics.totalOperations++;
1909
- this.sessionMetrics.totalDurationMs += usage.durationMs ?? 0;
1910
- this.sessionMetrics.totalInputTokens += usage.inputTokens ?? 0;
1911
- this.sessionMetrics.totalOutputTokens += usage.outputTokens ?? 0;
1912
- const count = this.sessionMetrics.operationCounts.get(usage.operation) ?? 0;
1913
- this.sessionMetrics.operationCounts.set(usage.operation, count + 1);
1914
- if (this.queue.length >= this.config.batchSize) this.flush();
1915
- }
1916
- async flush() {
1917
- if (this.isFlushing || this.queue.length === 0) return;
1918
- this.isFlushing = true;
1919
- const records = this.queue.splice(0, this.config.batchSize);
1920
- const providerFailed = /* @__PURE__ */ new Set();
1921
- const providerDone = /* @__PURE__ */ new Set();
1922
- try {
1923
- if (this.provider) {
1924
- const results = await Promise.allSettled(records.map((r) => this.provider?.recordUsage(r)));
1925
- for (let i = 0; i < records.length; i++) if (results[i].status === "rejected") providerFailed.add(records[i]);
1926
- else providerDone.add(records[i]);
1927
- if (providerFailed.size > 0) this.queue.unshift(...providerFailed);
1928
- }
1929
- if (this.storage) {
1930
- const toPersist = providerFailed.size > 0 ? records.filter((r) => !providerFailed.has(r)) : records;
1931
- if (toPersist.length > 0) await this.persistRecords(toPersist);
1932
- }
1933
- } catch (error) {
1934
- const firstFailed = typeof error?.firstFailedIndex === "number" ? error.firstFailedIndex : 0;
1935
- const unwritten = records.slice(firstFailed);
1936
- if (providerDone.size > 0) console.warn(`[usage-tracker] storage persistence failed for ${providerDone.size} provider-accepted records — local audit trail incomplete`, error instanceof Error ? error.message : String(error));
1937
- const unhandled = unwritten.filter((r) => !providerFailed.has(r) && !providerDone.has(r));
1938
- if (unhandled.length > 0) this.queue.unshift(...unhandled);
1939
- } finally {
1940
- this.isFlushing = false;
1941
- }
1942
- }
1943
- async getUsage(options) {
1944
- if (this.provider) return this.provider.getUsage({
1945
- projectRef: this.config.projectRef,
1946
- ...options
1947
- });
1948
- return this.loadPersistedRecords(options);
1949
- }
1950
- async getSummary(period = "day") {
1951
- if (this.provider) return this.provider.getSummary(this.config.projectRef, period);
1952
- return this.generateLocalSummary(period);
1953
- }
1954
- getSessionMetrics() {
1955
- return {
1956
- totalCredits: this.sessionMetrics.totalCredits,
1957
- totalOperations: this.sessionMetrics.totalOperations,
1958
- totalDurationMs: this.sessionMetrics.totalDurationMs,
1959
- totalInputTokens: this.sessionMetrics.totalInputTokens,
1960
- totalOutputTokens: this.sessionMetrics.totalOutputTokens,
1961
- operationBreakdown: Object.fromEntries(this.sessionMetrics.operationCounts),
1962
- sessionDurationMs: Date.now() - this.sessionMetrics.startTime
1963
- };
1964
- }
1965
- resetSessionMetrics() {
1966
- this.sessionMetrics = {
1967
- totalCredits: 0,
1968
- totalOperations: 0,
1969
- totalDurationMs: 0,
1970
- totalInputTokens: 0,
1971
- totalOutputTokens: 0,
1972
- operationCounts: /* @__PURE__ */ new Map(),
1973
- startTime: Date.now()
1974
- };
1975
- }
1976
- async close() {
1977
- this.stopFlushTimer();
1978
- await this.flush();
1979
- }
1980
- calculateCost(operation, factors) {
1981
- let cost = OPERATION_COSTS[operation] ?? OPERATION_COSTS.default;
1982
- if (factors.durationMs) cost += factors.durationMs / 1e3 * .001;
1983
- if (factors.requestSize) cost += factors.requestSize / 1024 * 1e-4;
1984
- if (factors.responseSize) cost += factors.responseSize / 1024 * 1e-4;
1985
- return Math.round(cost * 1e5) / 1e5;
1986
- }
1987
- async persistRecords(records) {
1988
- if (!this.storage) return;
1989
- const timestamp = Date.now();
1990
- for (let i = 0; i < records.length; i++) {
1991
- const record = records[i];
1992
- const id = `usage-${timestamp}-${i}`;
1993
- try {
1994
- await this.storage.set(`usage:${id}`, {
1995
- ...record,
1996
- id,
1997
- timestamp: /* @__PURE__ */ new Date()
1998
- });
1999
- } catch (err) {
2000
- throw Object.assign(err instanceof Error ? err : new Error(String(err)), { firstFailedIndex: i });
2001
- }
2002
- }
2003
- }
2004
- async loadPersistedRecords(options) {
2005
- if (!this.storage) return [];
2006
- const usageKeys = (await this.storage.keys()).filter((k) => k.startsWith("usage:"));
2007
- const records = [];
2008
- for (const key of usageKeys) {
2009
- const record = await this.storage.get(key);
2010
- if (!record) continue;
2011
- if (options?.since && record.timestamp < options.since) continue;
2012
- if (options?.until && record.timestamp > options.until) continue;
2013
- records.push(record);
2014
- }
2015
- records.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
2016
- return options?.limit ? records.slice(0, options.limit) : records;
2017
- }
2018
- async generateLocalSummary(period) {
2019
- const now = /* @__PURE__ */ new Date();
2020
- const periodStart = this.getPeriodStart(now, period);
2021
- const records = await this.loadPersistedRecords({
2022
- since: periodStart,
2023
- until: now
2024
- });
2025
- const operationBreakdown = {};
2026
- let totalCredits = 0;
2027
- let totalDurationMs = 0;
2028
- let totalInputTokens = 0;
2029
- let totalOutputTokens = 0;
2030
- for (const record of records) {
2031
- totalCredits += record.credits;
2032
- totalDurationMs += record.durationMs ?? 0;
2033
- totalInputTokens += record.inputTokens ?? 0;
2034
- totalOutputTokens += record.outputTokens ?? 0;
2035
- operationBreakdown[record.operation] = (operationBreakdown[record.operation] ?? 0) + 1;
2036
- }
2037
- return {
2038
- projectRef: this.config.projectRef,
2039
- period,
2040
- periodStart,
2041
- periodEnd: now,
2042
- totalCredits,
2043
- totalOperations: records.length,
2044
- totalDurationMs,
2045
- totalInputTokens,
2046
- totalOutputTokens,
2047
- operationBreakdown
2048
- };
2049
- }
2050
- getPeriodStart(now, period) {
2051
- const start = new Date(now);
2052
- switch (period) {
2053
- case "hour":
2054
- start.setMinutes(0, 0, 0);
2055
- break;
2056
- case "day":
2057
- start.setHours(0, 0, 0, 0);
2058
- break;
2059
- case "week":
2060
- start.setDate(start.getDate() - start.getDay());
2061
- start.setHours(0, 0, 0, 0);
2062
- break;
2063
- case "month":
2064
- start.setDate(1);
2065
- start.setHours(0, 0, 0, 0);
2066
- break;
2067
- }
2068
- return start;
2069
- }
2070
- startFlushTimer() {
2071
- if (this.flushTimer) return;
2072
- this.flushTimer = setInterval(() => this.flush(), this.config.flushIntervalMs);
2073
- }
2074
- stopFlushTimer() {
2075
- if (this.flushTimer) {
2076
- clearInterval(this.flushTimer);
2077
- this.flushTimer = void 0;
2078
- }
2079
- }
2080
- };
2081
- function createUsageInterceptor(tracker) {
2082
- return {
2083
- onRequest(ctx) {
2084
- return ctx;
2085
- },
2086
- onResponse(ctx) {
2087
- const durationMs = Date.now() - ctx.startedAt;
2088
- tracker.recordApiCall({
2089
- path: new URL(ctx.request.url).pathname,
2090
- method: ctx.request.method,
2091
- status: ctx.response.status,
2092
- durationMs,
2093
- timestamp: /* @__PURE__ */ new Date()
2094
- });
2095
- },
2096
- onError(ctx) {
2097
- const durationMs = Date.now() - ctx.startedAt;
2098
- tracker.recordApiCall({
2099
- path: new URL(ctx.request.url).pathname,
2100
- method: ctx.request.method,
2101
- status: 0,
2102
- durationMs,
2103
- error: ctx.error.message,
2104
- timestamp: /* @__PURE__ */ new Date()
2105
- });
2106
- }
2107
- };
2108
- }
2109
- function createUsageTracker(config, provider, storage) {
2110
- return new UsageTracker(config, provider, storage);
2111
- }
2112
- //#endregion
2113
- export { ConsoleTelemetrySink, CreditTracker, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, HttpTelemetrySink, LangfuseSink, MemoryCreditProvider, MultiTelemetrySink, ORCHESTRATOR_HOP_ID_HEADER, OtelTelemetrySink, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SSEChunkParser, SpanRecorder, StreamUsageExtractor, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TelemetryTracker, TestTelemetrySink, TraceCollector, UsageTracker, addTokenUsage, consumeSSEStream, createConsoleSink, createCreditTracker, createEmptyContext, createHttpSink, createLangfuseSinkFromEnv, createOtelSink, createOtelSinkFromEnv, createStreamUsageExtractor, createTelemetryTracker, createTestSink, createTraceCollector, createUsageCallback, createUsageInterceptor, createUsageTracker, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, initOtelProvider, isAdoptablePtid, isBuildResultEvent, isCompletionEvent, isCustomEvent, isDiagnosticEvent, isEnvironmentEvent, isErrorEvent, isFileChangeEvent, isFilePart, isMessagePartUpdatedEvent, isMessageUpdatedEvent, isReasoningPart, isTestResultEvent, isTextPart, isToolPart, mintPtid, monotonicNs, parseMetadataBlob, parseSSEData, parseSSEStream, parseServerTiming, readOrMintPtid, readTokenCostUsd, readTokenUsage, shutdownOtelProvider, spanDurationMs, sseToSignal, sseToTraceEvent, tokenCount, tokenUsageSource };
1398
+ export { ConsoleTelemetrySink, GEN_AI_CONVERSATION_ID, GEN_AI_INPUT_TOKEN_KEYS, GEN_AI_MODEL_KEYS, GEN_AI_OPERATION_NAME, GEN_AI_OUTPUT_TOKEN_KEYS, GEN_AI_REQUEST_MODEL, GEN_AI_RESPONSE_MODEL, GEN_AI_USAGE_INPUT_TOKENS, GEN_AI_USAGE_OUTPUT_TOKENS, HttpTelemetrySink, LangfuseSink, MultiTelemetrySink, ORCHESTRATOR_HOP_ID_HEADER, OtelTelemetrySink, PROVISION_TRACE_ID_HEADER, PTID_PREFIX, SSEChunkParser, SpanRecorder, StreamUsageExtractor, TOKEN_USAGE_COST_KEYS, TOKEN_USAGE_INPUT_KEYS, TOKEN_USAGE_OUTPUT_KEYS, TestTelemetrySink, TraceCollector, addTokenUsage, consumeSSEStream, createConsoleSink, createEmptyContext, createHttpSink, createLangfuseSinkFromEnv, createOtelSink, createOtelSinkFromEnv, createStreamUsageExtractor, createTestSink, createTraceCollector, createUsageCallback, firstTokenCount, firstUsageCostUsd, genAiUsageAttributes, initOtelProvider, isAdoptablePtid, isBuildResultEvent, isCompletionEvent, isCustomEvent, isDiagnosticEvent, isEnvironmentEvent, isErrorEvent, isFileChangeEvent, isFilePart, isMessagePartUpdatedEvent, isMessageUpdatedEvent, isReasoningPart, isTestResultEvent, isTextPart, isToolPart, mintPtid, monotonicNs, parseMetadataBlob, parseSSEData, parseSSEStream, parseServerTiming, readOrMintPtid, readTokenCostUsd, readTokenUsage, shutdownOtelProvider, spanDurationMs, sseToSignal, sseToTraceEvent, tokenCount, tokenUsageSource };
2114
1399
 
2115
1400
  //# sourceMappingURL=index.mjs.map