@nanocollective/nanocoder 1.15.1 → 1.16.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.
Files changed (145) hide show
  1. package/README.md +8 -1
  2. package/dist/ai-sdk-client.d.ts +5 -0
  3. package/dist/ai-sdk-client.d.ts.map +1 -1
  4. package/dist/ai-sdk-client.js +21 -3
  5. package/dist/ai-sdk-client.js.map +1 -1
  6. package/dist/app/utils/appUtils.d.ts.map +1 -1
  7. package/dist/app/utils/appUtils.js +5 -3
  8. package/dist/app/utils/appUtils.js.map +1 -1
  9. package/dist/commands/index.d.ts +1 -0
  10. package/dist/commands/index.d.ts.map +1 -1
  11. package/dist/commands/index.js +1 -0
  12. package/dist/commands/index.js.map +1 -1
  13. package/dist/commands/usage.d.ts +7 -0
  14. package/dist/commands/usage.d.ts.map +1 -0
  15. package/dist/commands/usage.js +69 -0
  16. package/dist/commands/usage.js.map +1 -0
  17. package/dist/commands.d.ts +3 -2
  18. package/dist/commands.d.ts.map +1 -1
  19. package/dist/commands.js.map +1 -1
  20. package/dist/components/usage/progress-bar.d.ts +14 -0
  21. package/dist/components/usage/progress-bar.d.ts.map +1 -0
  22. package/dist/components/usage/progress-bar.js +14 -0
  23. package/dist/components/usage/progress-bar.js.map +1 -0
  24. package/dist/components/usage/usage-display.d.ts +18 -0
  25. package/dist/components/usage/usage-display.d.ts.map +1 -0
  26. package/dist/components/usage/usage-display.js +50 -0
  27. package/dist/components/usage/usage-display.js.map +1 -0
  28. package/dist/config/paths.d.ts +0 -4
  29. package/dist/config/paths.d.ts.map +1 -1
  30. package/dist/config/paths.js +2 -18
  31. package/dist/config/paths.js.map +1 -1
  32. package/dist/hooks/useAppInitialization.d.ts.map +1 -1
  33. package/dist/hooks/useAppInitialization.js +2 -1
  34. package/dist/hooks/useAppInitialization.js.map +1 -1
  35. package/dist/hooks/useAppState.d.ts +2 -0
  36. package/dist/hooks/useAppState.d.ts.map +1 -1
  37. package/dist/hooks/useAppState.js +27 -5
  38. package/dist/hooks/useAppState.js.map +1 -1
  39. package/dist/hooks/useChatHandler.d.ts.map +1 -1
  40. package/dist/hooks/useChatHandler.js +45 -9
  41. package/dist/hooks/useChatHandler.js.map +1 -1
  42. package/dist/models/index.d.ts +2 -0
  43. package/dist/models/index.d.ts.map +1 -0
  44. package/dist/models/index.js +2 -0
  45. package/dist/models/index.js.map +1 -0
  46. package/dist/models/models-cache.d.ts +8 -0
  47. package/dist/models/models-cache.d.ts.map +1 -0
  48. package/dist/models/models-cache.js +63 -0
  49. package/dist/models/models-cache.js.map +1 -0
  50. package/dist/models/models-dev-client.d.ts +10 -0
  51. package/dist/models/models-dev-client.d.ts.map +1 -0
  52. package/dist/models/models-dev-client.js +268 -0
  53. package/dist/models/models-dev-client.js.map +1 -0
  54. package/dist/models/models-types.d.ts +66 -0
  55. package/dist/models/models-types.d.ts.map +1 -0
  56. package/dist/models/models-types.js +5 -0
  57. package/dist/models/models-types.js.map +1 -0
  58. package/dist/recommendations/model-database.d.ts.map +1 -1
  59. package/dist/recommendations/model-database.js +45 -0
  60. package/dist/recommendations/model-database.js.map +1 -1
  61. package/dist/tokenization/index.d.ts +2 -0
  62. package/dist/tokenization/index.d.ts.map +1 -0
  63. package/dist/tokenization/index.js +2 -0
  64. package/dist/tokenization/index.js.map +1 -0
  65. package/dist/tokenization/tokenizer-factory.d.ts +14 -0
  66. package/dist/tokenization/tokenizer-factory.d.ts.map +1 -0
  67. package/dist/tokenization/tokenizer-factory.js +90 -0
  68. package/dist/tokenization/tokenizer-factory.js.map +1 -0
  69. package/dist/tokenization/tokenizer-factory.spec.d.ts +5 -0
  70. package/dist/tokenization/tokenizer-factory.spec.d.ts.map +1 -0
  71. package/dist/tokenization/tokenizer-factory.spec.js +137 -0
  72. package/dist/tokenization/tokenizer-factory.spec.js.map +1 -0
  73. package/dist/tokenization/tokenizers/anthropic-tokenizer.d.ts +17 -0
  74. package/dist/tokenization/tokenizers/anthropic-tokenizer.d.ts.map +1 -0
  75. package/dist/tokenization/tokenizers/anthropic-tokenizer.js +35 -0
  76. package/dist/tokenization/tokenizers/anthropic-tokenizer.js.map +1 -0
  77. package/dist/tokenization/tokenizers/anthropic-tokenizer.spec.d.ts +5 -0
  78. package/dist/tokenization/tokenizers/anthropic-tokenizer.spec.d.ts.map +1 -0
  79. package/dist/tokenization/tokenizers/anthropic-tokenizer.spec.js +152 -0
  80. package/dist/tokenization/tokenizers/anthropic-tokenizer.spec.js.map +1 -0
  81. package/dist/tokenization/tokenizers/fallback-tokenizer.d.ts +13 -0
  82. package/dist/tokenization/tokenizers/fallback-tokenizer.d.ts.map +1 -0
  83. package/dist/tokenization/tokenizers/fallback-tokenizer.js +20 -0
  84. package/dist/tokenization/tokenizers/fallback-tokenizer.js.map +1 -0
  85. package/dist/tokenization/tokenizers/fallback-tokenizer.spec.d.ts +5 -0
  86. package/dist/tokenization/tokenizers/fallback-tokenizer.spec.d.ts.map +1 -0
  87. package/dist/tokenization/tokenizers/fallback-tokenizer.spec.js +183 -0
  88. package/dist/tokenization/tokenizers/fallback-tokenizer.spec.js.map +1 -0
  89. package/dist/tokenization/tokenizers/llama-tokenizer.d.ts +14 -0
  90. package/dist/tokenization/tokenizers/llama-tokenizer.d.ts.map +1 -0
  91. package/dist/tokenization/tokenizers/llama-tokenizer.js +33 -0
  92. package/dist/tokenization/tokenizers/llama-tokenizer.js.map +1 -0
  93. package/dist/tokenization/tokenizers/llama-tokenizer.spec.d.ts +5 -0
  94. package/dist/tokenization/tokenizers/llama-tokenizer.spec.d.ts.map +1 -0
  95. package/dist/tokenization/tokenizers/llama-tokenizer.spec.js +170 -0
  96. package/dist/tokenization/tokenizers/llama-tokenizer.spec.js.map +1 -0
  97. package/dist/tokenization/tokenizers/openai-tokenizer.d.ts +22 -0
  98. package/dist/tokenization/tokenizers/openai-tokenizer.d.ts.map +1 -0
  99. package/dist/tokenization/tokenizers/openai-tokenizer.js +48 -0
  100. package/dist/tokenization/tokenizers/openai-tokenizer.js.map +1 -0
  101. package/dist/tokenization/tokenizers/openai-tokenizer.spec.d.ts +5 -0
  102. package/dist/tokenization/tokenizers/openai-tokenizer.spec.d.ts.map +1 -0
  103. package/dist/tokenization/tokenizers/openai-tokenizer.spec.js +140 -0
  104. package/dist/tokenization/tokenizers/openai-tokenizer.spec.js.map +1 -0
  105. package/dist/types/commands.d.ts +1 -0
  106. package/dist/types/commands.d.ts.map +1 -1
  107. package/dist/types/tokenization.d.ts +31 -0
  108. package/dist/types/tokenization.d.ts.map +1 -0
  109. package/dist/types/tokenization.js +5 -0
  110. package/dist/types/tokenization.js.map +1 -0
  111. package/dist/types/usage.d.ts +55 -0
  112. package/dist/types/usage.d.ts.map +1 -0
  113. package/dist/types/usage.js +2 -0
  114. package/dist/types/usage.js.map +1 -0
  115. package/dist/usage/calculator.d.ts +28 -0
  116. package/dist/usage/calculator.d.ts.map +1 -0
  117. package/dist/usage/calculator.js +81 -0
  118. package/dist/usage/calculator.js.map +1 -0
  119. package/dist/usage/calculator.spec.d.ts +2 -0
  120. package/dist/usage/calculator.spec.d.ts.map +1 -0
  121. package/dist/usage/calculator.spec.js +303 -0
  122. package/dist/usage/calculator.spec.js.map +1 -0
  123. package/dist/usage/storage.d.ts +19 -0
  124. package/dist/usage/storage.d.ts.map +1 -0
  125. package/dist/usage/storage.js +134 -0
  126. package/dist/usage/storage.js.map +1 -0
  127. package/dist/usage/storage.spec.d.ts +2 -0
  128. package/dist/usage/storage.spec.d.ts.map +1 -0
  129. package/dist/usage/storage.spec.js +417 -0
  130. package/dist/usage/storage.spec.js.map +1 -0
  131. package/dist/usage/tracker.d.ts +28 -0
  132. package/dist/usage/tracker.d.ts.map +1 -0
  133. package/dist/usage/tracker.js +75 -0
  134. package/dist/usage/tracker.js.map +1 -0
  135. package/dist/usage/tracker.spec.d.ts +2 -0
  136. package/dist/usage/tracker.spec.d.ts.map +1 -0
  137. package/dist/usage/tracker.spec.js +347 -0
  138. package/dist/usage/tracker.spec.js.map +1 -0
  139. package/dist/utils/paste-roundtrip.spec.d.ts.map +1 -0
  140. package/dist/utils/paste-roundtrip.spec.js.map +1 -0
  141. package/package.json +7 -2
  142. package/dist/integration/paste-roundtrip.spec.d.ts.map +0 -1
  143. package/dist/integration/paste-roundtrip.spec.js.map +0 -1
  144. /package/dist/{integration → utils}/paste-roundtrip.spec.d.ts +0 -0
  145. /package/dist/{integration → utils}/paste-roundtrip.spec.js +0 -0
@@ -0,0 +1,417 @@
1
+ import test from 'ava';
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import * as os from 'node:os';
5
+ import { readUsageData, writeUsageData, addSession, getTodayAggregate, getLastNDaysAggregate, clearUsageData, } from './storage.js';
6
+ console.log('\nstorage.spec.ts');
7
+ // ============================================================================
8
+ // Test Setup
9
+ // ============================================================================
10
+ // Create a temporary test directory for each test
11
+ function createTestDir() {
12
+ const testDir = path.join(os.tmpdir(), `nanocoder-test-${Date.now()}-${Math.random().toString(36).substring(7)}`);
13
+ fs.mkdirSync(testDir, { recursive: true });
14
+ return testDir;
15
+ }
16
+ // Mock getAppDataPath to use test directory
17
+ let originalEnv;
18
+ test.before(() => {
19
+ originalEnv = { ...process.env };
20
+ });
21
+ test.beforeEach(() => {
22
+ // Create a fresh test directory for each test
23
+ const testDir = createTestDir();
24
+ // Override XDG_DATA_HOME to point to test directory (used by xdgData)
25
+ process.env.XDG_DATA_HOME = testDir;
26
+ // Clear any existing data
27
+ clearUsageData();
28
+ });
29
+ test.afterEach(() => {
30
+ // Clear usage data first
31
+ clearUsageData();
32
+ // Clean up test directory
33
+ try {
34
+ if (process.env.XDG_DATA_HOME) {
35
+ fs.rmSync(process.env.XDG_DATA_HOME, { recursive: true, force: true });
36
+ }
37
+ }
38
+ catch (error) {
39
+ // Ignore cleanup errors
40
+ }
41
+ });
42
+ test.after(() => {
43
+ process.env = originalEnv;
44
+ });
45
+ // Helper to create mock token breakdown
46
+ function createMockBreakdown(total = 1000) {
47
+ return {
48
+ system: Math.floor(total * 0.3),
49
+ userMessages: Math.floor(total * 0.2),
50
+ assistantMessages: Math.floor(total * 0.3),
51
+ toolResults: Math.floor(total * 0.1),
52
+ toolDefinitions: Math.floor(total * 0.1),
53
+ total,
54
+ };
55
+ }
56
+ // Helper to create mock session
57
+ function createMockSession(provider = 'test-provider', model = 'test-model', tokens = 1000) {
58
+ return {
59
+ id: `session-${Date.now()}`,
60
+ timestamp: Date.now(),
61
+ provider,
62
+ model,
63
+ tokens: createMockBreakdown(tokens),
64
+ messageCount: 10,
65
+ duration: 60000,
66
+ };
67
+ }
68
+ // ============================================================================
69
+ // readUsageData Tests
70
+ // ============================================================================
71
+ test('readUsageData returns empty data when file does not exist', t => {
72
+ const data = readUsageData();
73
+ t.is(data.sessions.length, 0);
74
+ t.is(data.dailyAggregates.length, 0);
75
+ t.is(data.totalLifetime, 0);
76
+ t.truthy(data.lastUpdated);
77
+ });
78
+ test('readUsageData returns empty data on read error', t => {
79
+ // Write invalid JSON
80
+ const dataHome = process.env.XDG_DATA_HOME || path.join(os.tmpdir(), 'test-data');
81
+ const configDir = path.join(dataHome, 'nanocoder');
82
+ fs.mkdirSync(configDir, { recursive: true });
83
+ fs.writeFileSync(path.join(configDir, 'usage.json'), 'invalid json', 'utf-8');
84
+ const data = readUsageData();
85
+ t.is(data.sessions.length, 0);
86
+ t.is(data.dailyAggregates.length, 0);
87
+ t.is(data.totalLifetime, 0);
88
+ });
89
+ test('readUsageData reads existing data', t => {
90
+ // Write valid data first
91
+ const mockData = {
92
+ sessions: [createMockSession()],
93
+ dailyAggregates: [],
94
+ totalLifetime: 1000,
95
+ lastUpdated: Date.now(),
96
+ };
97
+ writeUsageData(mockData);
98
+ const data = readUsageData();
99
+ t.is(data.sessions.length, 1);
100
+ t.is(data.totalLifetime, 1000);
101
+ });
102
+ // ============================================================================
103
+ // writeUsageData Tests
104
+ // ============================================================================
105
+ test('writeUsageData creates and writes data successfully', t => {
106
+ const mockData = {
107
+ sessions: [createMockSession()],
108
+ dailyAggregates: [],
109
+ totalLifetime: 1000,
110
+ lastUpdated: Date.now(),
111
+ };
112
+ // Write data
113
+ writeUsageData(mockData);
114
+ // Read it back
115
+ const data = readUsageData();
116
+ t.is(data.sessions.length, 1);
117
+ t.is(data.totalLifetime, 1000);
118
+ });
119
+ test('writeUsageData writes data to file', t => {
120
+ const mockData = {
121
+ sessions: [createMockSession()],
122
+ dailyAggregates: [],
123
+ totalLifetime: 1000,
124
+ lastUpdated: Date.now(),
125
+ };
126
+ writeUsageData(mockData);
127
+ const data = readUsageData();
128
+ t.is(data.sessions.length, 1);
129
+ t.is(data.totalLifetime, 1000);
130
+ });
131
+ test('writeUsageData updates lastUpdated timestamp', t => {
132
+ const oldTimestamp = Date.now() - 10000;
133
+ const mockData = {
134
+ sessions: [],
135
+ dailyAggregates: [],
136
+ totalLifetime: 0,
137
+ lastUpdated: oldTimestamp,
138
+ };
139
+ writeUsageData(mockData);
140
+ const data = readUsageData();
141
+ t.true(data.lastUpdated > oldTimestamp);
142
+ });
143
+ test('writeUsageData handles write errors gracefully', t => {
144
+ const dataHome = process.env.XDG_DATA_HOME || path.join(os.tmpdir(), 'test-data');
145
+ const configDir = path.join(dataHome, 'nanocoder');
146
+ // Make directory if needed, then make it read-only
147
+ fs.mkdirSync(configDir, { recursive: true });
148
+ fs.chmodSync(configDir, 0o444);
149
+ const mockData = {
150
+ sessions: [],
151
+ dailyAggregates: [],
152
+ totalLifetime: 0,
153
+ lastUpdated: Date.now(),
154
+ };
155
+ // Should not throw
156
+ t.notThrows(() => writeUsageData(mockData));
157
+ // Restore permissions for cleanup
158
+ fs.chmodSync(configDir, 0o755);
159
+ });
160
+ // ============================================================================
161
+ // addSession Tests
162
+ // ============================================================================
163
+ test('addSession adds new session to empty data', t => {
164
+ const session = createMockSession();
165
+ addSession(session);
166
+ const data = readUsageData();
167
+ t.is(data.sessions.length, 1);
168
+ t.is(data.sessions[0].id, session.id);
169
+ t.is(data.totalLifetime, session.tokens.total);
170
+ });
171
+ test('addSession adds session to beginning of list', t => {
172
+ const session1 = createMockSession('provider1', 'model1', 1000);
173
+ const session2 = createMockSession('provider2', 'model2', 2000);
174
+ addSession(session1);
175
+ addSession(session2);
176
+ const data = readUsageData();
177
+ t.is(data.sessions.length, 2);
178
+ t.is(data.sessions[0].id, session2.id); // Most recent first
179
+ t.is(data.sessions[1].id, session1.id);
180
+ });
181
+ test('addSession updates total lifetime tokens', t => {
182
+ const session1 = createMockSession('provider1', 'model1', 1000);
183
+ const session2 = createMockSession('provider2', 'model2', 2000);
184
+ addSession(session1);
185
+ addSession(session2);
186
+ const data = readUsageData();
187
+ t.is(data.totalLifetime, 3000);
188
+ });
189
+ test('addSession limits sessions to MAX_SESSIONS (100)', t => {
190
+ // Add 101 sessions
191
+ for (let i = 0; i < 101; i++) {
192
+ const session = createMockSession(`provider-${i}`, `model-${i}`, 100);
193
+ addSession(session);
194
+ }
195
+ const data = readUsageData();
196
+ t.is(data.sessions.length, 100); // Should be limited to 100
197
+ });
198
+ test('addSession creates daily aggregate', t => {
199
+ const session = createMockSession();
200
+ addSession(session);
201
+ const data = readUsageData();
202
+ t.is(data.dailyAggregates.length, 1);
203
+ const today = new Date().toISOString().split('T')[0];
204
+ const aggregate = data.dailyAggregates.find(agg => agg.date === today);
205
+ t.truthy(aggregate);
206
+ t.is(aggregate.sessions, 1);
207
+ t.is(aggregate.totalTokens, session.tokens.total);
208
+ });
209
+ test('addSession updates existing daily aggregate', t => {
210
+ const session1 = createMockSession('provider1', 'model1', 1000);
211
+ const session2 = createMockSession('provider2', 'model2', 2000);
212
+ addSession(session1);
213
+ addSession(session2);
214
+ const data = readUsageData();
215
+ const today = new Date().toISOString().split('T')[0];
216
+ const aggregate = data.dailyAggregates.find(agg => agg.date === today);
217
+ t.truthy(aggregate);
218
+ t.is(aggregate.sessions, 2);
219
+ t.is(aggregate.totalTokens, 3000);
220
+ });
221
+ test('addSession tracks provider stats in daily aggregate', t => {
222
+ const session1 = createMockSession('openai', 'gpt-4', 1000);
223
+ const session2 = createMockSession('openai', 'gpt-3.5', 2000);
224
+ const session3 = createMockSession('anthropic', 'claude', 3000);
225
+ addSession(session1);
226
+ addSession(session2);
227
+ addSession(session3);
228
+ const data = readUsageData();
229
+ const today = new Date().toISOString().split('T')[0];
230
+ const aggregate = data.dailyAggregates.find(agg => agg.date === today);
231
+ t.truthy(aggregate);
232
+ t.is(aggregate.providers.openai, 3000); // 1000 + 2000
233
+ t.is(aggregate.providers.anthropic, 3000);
234
+ });
235
+ test('addSession tracks model stats in daily aggregate', t => {
236
+ const session1 = createMockSession('openai', 'gpt-4', 1000);
237
+ const session2 = createMockSession('openai', 'gpt-4', 2000);
238
+ const session3 = createMockSession('openai', 'gpt-3.5', 3000);
239
+ addSession(session1);
240
+ addSession(session2);
241
+ addSession(session3);
242
+ const data = readUsageData();
243
+ const today = new Date().toISOString().split('T')[0];
244
+ const aggregate = data.dailyAggregates.find(agg => agg.date === today);
245
+ t.truthy(aggregate);
246
+ t.is(aggregate.models['gpt-4'], 3000); // 1000 + 2000
247
+ t.is(aggregate.models['gpt-3.5'], 3000);
248
+ });
249
+ test('addSession limits daily aggregates to MAX_DAILY_AGGREGATES (30)', t => {
250
+ // Create sessions with different dates
251
+ for (let i = 0; i < 35; i++) {
252
+ const session = createMockSession();
253
+ // Modify timestamp to be i days ago
254
+ session.timestamp = Date.now() - i * 24 * 60 * 60 * 1000;
255
+ addSession(session);
256
+ }
257
+ const data = readUsageData();
258
+ t.is(data.dailyAggregates.length, 30); // Should be limited to 30
259
+ });
260
+ // ============================================================================
261
+ // getTodayAggregate Tests
262
+ // ============================================================================
263
+ test('getTodayAggregate returns null when no data exists', t => {
264
+ const aggregate = getTodayAggregate();
265
+ t.is(aggregate, null);
266
+ });
267
+ test('getTodayAggregate returns null when no sessions today', t => {
268
+ // Add a session from yesterday
269
+ const session = createMockSession();
270
+ session.timestamp = Date.now() - 24 * 60 * 60 * 1000;
271
+ addSession(session);
272
+ const aggregate = getTodayAggregate();
273
+ t.is(aggregate, null);
274
+ });
275
+ test('getTodayAggregate returns today aggregate', t => {
276
+ const session = createMockSession('openai', 'gpt-4', 1000);
277
+ addSession(session);
278
+ const aggregate = getTodayAggregate();
279
+ t.truthy(aggregate);
280
+ t.is(aggregate.sessions, 1);
281
+ t.is(aggregate.totalTokens, 1000);
282
+ t.is(aggregate.date, new Date().toISOString().split('T')[0]);
283
+ });
284
+ // ============================================================================
285
+ // getLastNDaysAggregate Tests
286
+ // ============================================================================
287
+ test('getLastNDaysAggregate returns zero when no data exists', t => {
288
+ const result = getLastNDaysAggregate(7);
289
+ t.is(result.totalTokens, 0);
290
+ t.is(result.totalSessions, 0);
291
+ t.is(result.avgTokensPerDay, 0);
292
+ });
293
+ test('getLastNDaysAggregate calculates totals for last 7 days', t => {
294
+ // Add sessions for the past 5 days
295
+ for (let i = 0; i < 5; i++) {
296
+ const session = createMockSession('openai', 'gpt-4', 1000);
297
+ session.timestamp = Date.now() - i * 24 * 60 * 60 * 1000;
298
+ addSession(session);
299
+ }
300
+ const result = getLastNDaysAggregate(7);
301
+ t.is(result.totalTokens, 5000);
302
+ t.is(result.totalSessions, 5);
303
+ t.is(result.avgTokensPerDay, Math.round(5000 / 7));
304
+ });
305
+ test('getLastNDaysAggregate filters out older sessions', t => {
306
+ // Add 3 sessions within last 7 days
307
+ for (let i = 0; i < 3; i++) {
308
+ const session = createMockSession('openai', 'gpt-4', 1000);
309
+ session.timestamp = Date.now() - i * 24 * 60 * 60 * 1000;
310
+ addSession(session);
311
+ }
312
+ // Add 2 sessions older than 7 days
313
+ for (let i = 8; i < 10; i++) {
314
+ const session = createMockSession('openai', 'gpt-4', 1000);
315
+ session.timestamp = Date.now() - i * 24 * 60 * 60 * 1000;
316
+ addSession(session);
317
+ }
318
+ const result = getLastNDaysAggregate(7);
319
+ // Should only count the 3 recent sessions
320
+ t.is(result.totalTokens, 3000);
321
+ t.is(result.totalSessions, 3);
322
+ });
323
+ test('getLastNDaysAggregate handles different day ranges', t => {
324
+ // Add sessions for the past 10 days
325
+ for (let i = 0; i < 10; i++) {
326
+ const session = createMockSession('openai', 'gpt-4', 1000);
327
+ session.timestamp = Date.now() - i * 24 * 60 * 60 * 1000;
328
+ addSession(session);
329
+ }
330
+ const result7 = getLastNDaysAggregate(7);
331
+ const result30 = getLastNDaysAggregate(30);
332
+ // 7 days should include days 0-6 (7 sessions)
333
+ // But depending on timing, might include day 7 too if timestamps align
334
+ t.true(result7.totalTokens >= 7000 && result7.totalTokens <= 8000);
335
+ t.is(result30.totalTokens, 10000);
336
+ });
337
+ test('getLastNDaysAggregate calculates average correctly', t => {
338
+ // Add 10 sessions over 5 days
339
+ for (let i = 0; i < 10; i++) {
340
+ const session = createMockSession('openai', 'gpt-4', 500);
341
+ session.timestamp = Date.now() - (i % 5) * 24 * 60 * 60 * 1000;
342
+ addSession(session);
343
+ }
344
+ const result = getLastNDaysAggregate(7);
345
+ // 10 sessions * 500 tokens = 5000 total
346
+ // Average over 7 days = 5000 / 7 ≈ 714
347
+ t.is(result.totalTokens, 5000);
348
+ t.is(result.avgTokensPerDay, Math.round(5000 / 7));
349
+ });
350
+ // ============================================================================
351
+ // clearUsageData Tests
352
+ // ============================================================================
353
+ test('clearUsageData removes usage file', t => {
354
+ // Add some data first
355
+ const session = createMockSession();
356
+ addSession(session);
357
+ // Verify data exists
358
+ let data = readUsageData();
359
+ t.is(data.sessions.length, 1);
360
+ // Clear data
361
+ clearUsageData();
362
+ // Verify data is empty
363
+ data = readUsageData();
364
+ t.is(data.sessions.length, 0);
365
+ t.is(data.totalLifetime, 0);
366
+ });
367
+ test('clearUsageData handles non-existent file', t => {
368
+ // Should not throw even if file doesn't exist
369
+ t.notThrows(() => clearUsageData());
370
+ });
371
+ test('clearUsageData is idempotent', t => {
372
+ // Add and clear data
373
+ addSession(createMockSession());
374
+ clearUsageData();
375
+ // Clear again
376
+ t.notThrows(() => clearUsageData());
377
+ // Verify still empty
378
+ const data = readUsageData();
379
+ t.is(data.sessions.length, 0);
380
+ });
381
+ // ============================================================================
382
+ // Integration Tests
383
+ // ============================================================================
384
+ test('complete usage tracking flow', t => {
385
+ // Start with empty data
386
+ let data = readUsageData();
387
+ t.is(data.sessions.length, 0);
388
+ // Add multiple sessions
389
+ const session1 = createMockSession('openai', 'gpt-4', 1000);
390
+ const session2 = createMockSession('anthropic', 'claude', 2000);
391
+ const session3 = createMockSession('openai', 'gpt-3.5', 1500);
392
+ addSession(session1);
393
+ addSession(session2);
394
+ addSession(session3);
395
+ // Verify sessions added
396
+ data = readUsageData();
397
+ t.is(data.sessions.length, 3);
398
+ t.is(data.totalLifetime, 4500);
399
+ // Verify daily aggregate
400
+ const today = new Date().toISOString().split('T')[0];
401
+ const aggregate = data.dailyAggregates.find(agg => agg.date === today);
402
+ t.truthy(aggregate);
403
+ t.is(aggregate.sessions, 3);
404
+ t.is(aggregate.totalTokens, 4500);
405
+ // Verify getTodayAggregate
406
+ const todayAgg = getTodayAggregate();
407
+ t.is(todayAgg.totalTokens, 4500);
408
+ // Verify getLastNDaysAggregate
409
+ const weekStats = getLastNDaysAggregate(7);
410
+ t.is(weekStats.totalTokens, 4500);
411
+ t.is(weekStats.totalSessions, 3);
412
+ // Clear and verify
413
+ clearUsageData();
414
+ data = readUsageData();
415
+ t.is(data.sessions.length, 0);
416
+ });
417
+ //# sourceMappingURL=storage.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.spec.js","sourceRoot":"","sources":["../../source/usage/storage.spec.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,KAAK,CAAC;AACvB,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EACN,aAAa,EACb,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;AAEjC,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,kDAAkD;AAClD,SAAS,aAAa;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CACxB,EAAE,CAAC,MAAM,EAAE,EACX,kBAAkB,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CACzE,CAAC;IACF,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IACzC,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,4CAA4C;AAC5C,IAAI,WAA8B,CAAC;AAEnC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE;IAChB,WAAW,GAAG,EAAC,GAAG,OAAO,CAAC,GAAG,EAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE;IACpB,8CAA8C;IAC9C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,sEAAsE;IACtE,OAAO,CAAC,GAAG,CAAC,aAAa,GAAG,OAAO,CAAC;IACpC,0BAA0B;IAC1B,cAAc,EAAE,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE;IACnB,yBAAyB;IACzB,cAAc,EAAE,CAAC;IACjB,0BAA0B;IAC1B,IAAI,CAAC;QACJ,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC/B,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,EAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;QACtE,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,wBAAwB;IACzB,CAAC;AACF,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;IACf,OAAO,CAAC,GAAG,GAAG,WAAW,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEH,wCAAwC;AACxC,SAAS,mBAAmB,CAAC,KAAK,GAAG,IAAI;IACxC,OAAO;QACN,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QAC/B,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QACrC,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QAC1C,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QACpC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QACxC,KAAK;KACL,CAAC;AACH,CAAC;AAED,gCAAgC;AAChC,SAAS,iBAAiB,CACzB,QAAQ,GAAG,eAAe,EAC1B,KAAK,GAAG,YAAY,EACpB,MAAM,GAAG,IAAI;IAEb,OAAO;QACN,EAAE,EAAE,WAAW,IAAI,CAAC,GAAG,EAAE,EAAE;QAC3B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,QAAQ;QACR,KAAK;QACL,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC;QACnC,YAAY,EAAE,EAAE;QAChB,QAAQ,EAAE,KAAK;KACf,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,sBAAsB;AACtB,+EAA+E;AAE/E,IAAI,CAAC,2DAA2D,EAAE,CAAC,CAAC,EAAE;IACrE,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAE7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;AAC5B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gDAAgD,EAAE,CAAC,CAAC,EAAE;IAC1D,qBAAqB;IACrB,MAAM,QAAQ,GACb,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACnD,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IAC3C,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;IAE9E,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAE7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC,EAAE;IAC7C,yBAAyB;IACzB,MAAM,QAAQ,GAAc;QAC3B,QAAQ,EAAE,CAAC,iBAAiB,EAAE,CAAC;QAC/B,eAAe,EAAE,EAAE;QACnB,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;KACvB,CAAC;IAEF,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAE7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,IAAI,CAAC,qDAAqD,EAAE,CAAC,CAAC,EAAE;IAC/D,MAAM,QAAQ,GAAc;QAC3B,QAAQ,EAAE,CAAC,iBAAiB,EAAE,CAAC;QAC/B,eAAe,EAAE,EAAE;QACnB,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;KACvB,CAAC;IAEF,aAAa;IACb,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzB,eAAe;IACf,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oCAAoC,EAAE,CAAC,CAAC,EAAE;IAC9C,MAAM,QAAQ,GAAc;QAC3B,QAAQ,EAAE,CAAC,iBAAiB,EAAE,CAAC;QAC/B,eAAe,EAAE,EAAE;QACnB,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;KACvB,CAAC;IAEF,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8CAA8C,EAAE,CAAC,CAAC,EAAE;IACxD,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IACxC,MAAM,QAAQ,GAAc;QAC3B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,EAAE;QACnB,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,YAAY;KACzB,CAAC;IAEF,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gDAAgD,EAAE,CAAC,CAAC,EAAE;IAC1D,MAAM,QAAQ,GACb,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEnD,mDAAmD;IACnD,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IAC3C,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAE/B,MAAM,QAAQ,GAAc;QAC3B,QAAQ,EAAE,EAAE;QACZ,eAAe,EAAE,EAAE;QACnB,aAAa,EAAE,CAAC;QAChB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE;KACvB,CAAC;IAEF,mBAAmB;IACnB,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAE5C,kCAAkC;IAClC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,IAAI,CAAC,2CAA2C,EAAE,CAAC,CAAC,EAAE;IACrD,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8CAA8C,EAAE,CAAC,CAAC,EAAE;IACxD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEhE,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB;IAC7D,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0CAA0C,EAAE,CAAC,CAAC,EAAE;IACpD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEhE,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,CAAC,CAAC,EAAE;IAC5D,mBAAmB;IACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,iBAAiB,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACtE,UAAU,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,2BAA2B;AAC7D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oCAAoC,EAAE,CAAC,CAAC,EAAE;IAC9C,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IAEpC,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAErC,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IAEvE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpB,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,6CAA6C,EAAE,CAAC,CAAC,EAAE;IACvD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEhE,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IAEvE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpB,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qDAAqD,EAAE,CAAC,CAAC,EAAE;IAC/D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEhE,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IAEvE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpB,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,cAAc;IACvD,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,CAAC,CAAC,EAAE;IAC5D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAE9D,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IAEvE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpB,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,cAAc;IACtD,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,CAAC,CAAC,EAAE;IAC3E,uCAAuC;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;QACpC,oCAAoC;QACpC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACzD,UAAU,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,0BAA0B;AAClE,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E,IAAI,CAAC,oDAAoD,EAAE,CAAC,CAAC,EAAE;IAC9D,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;IACtC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uDAAuD,EAAE,CAAC,CAAC,EAAE;IACjE,+BAA+B;IAC/B,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IACrD,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpB,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;IACtC,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2CAA2C,EAAE,CAAC,CAAC,EAAE;IACrD,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC3D,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpB,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;IAEtC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpB,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E,IAAI,CAAC,wDAAwD,EAAE,CAAC,CAAC,EAAE;IAClE,MAAM,MAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAExC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yDAAyD,EAAE,CAAC,CAAC,EAAE;IACnE,mCAAmC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACzD,UAAU,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAExC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,CAAC,CAAC,EAAE;IAC5D,oCAAoC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACzD,UAAU,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,mCAAmC;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACzD,UAAU,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAExC,0CAA0C;IAC1C,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oDAAoD,EAAE,CAAC,CAAC,EAAE;IAC9D,oCAAoC;IACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACzD,UAAU,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,OAAO,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAC;IAE3C,8CAA8C;IAC9C,uEAAuE;IACvE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AACnC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oDAAoD,EAAE,CAAC,CAAC,EAAE;IAC9D,8BAA8B;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QAC/D,UAAU,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAExC,wCAAwC;IACxC,uCAAuC;IACvC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,IAAI,CAAC,mCAAmC,EAAE,CAAC,CAAC,EAAE;IAC7C,sBAAsB;IACtB,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,UAAU,CAAC,OAAO,CAAC,CAAC;IAEpB,qBAAqB;IACrB,IAAI,IAAI,GAAG,aAAa,EAAE,CAAC;IAC3B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAE9B,aAAa;IACb,cAAc,EAAE,CAAC;IAEjB,uBAAuB;IACvB,IAAI,GAAG,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,0CAA0C,EAAE,CAAC,CAAC,EAAE;IACpD,8CAA8C;IAC9C,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;AACrC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,8BAA8B,EAAE,CAAC,CAAC,EAAE;IACxC,qBAAqB;IACrB,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAChC,cAAc,EAAE,CAAC;IAEjB,cAAc;IACd,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC;IAEpC,qBAAqB;IACrB,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEH,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E,IAAI,CAAC,8BAA8B,EAAE,CAAC,CAAC,EAAE;IACxC,wBAAwB;IACxB,IAAI,IAAI,GAAG,aAAa,EAAE,CAAC;IAC3B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAE9B,wBAAwB;IACxB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAE9D,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IACrB,UAAU,CAAC,QAAQ,CAAC,CAAC;IAErB,wBAAwB;IACxB,IAAI,GAAG,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAE/B,yBAAyB;IACzB,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC;IACvE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpB,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,EAAE,CAAC,SAAU,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAEnC,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,CAAC,CAAC,EAAE,CAAC,QAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAElC,+BAA+B;IAC/B,MAAM,SAAS,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAEjC,mBAAmB;IACnB,cAAc,EAAE,CAAC;IACjB,IAAI,GAAG,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Usage tracker
3
+ * Tracks current session usage
4
+ */
5
+ import type { Message } from '../types/core.js';
6
+ import type { Tokenizer } from '../types/tokenization.js';
7
+ import type { CurrentSessionStats } from '../types/usage.js';
8
+ export declare class SessionTracker {
9
+ private sessionId;
10
+ private startTime;
11
+ private provider;
12
+ private model;
13
+ constructor(provider: string, model: string);
14
+ private generateSessionId;
15
+ getCurrentStats(messages: Message[], tokenizer: Tokenizer): Promise<CurrentSessionStats>;
16
+ saveSession(messages: Message[], tokenizer: Tokenizer): void;
17
+ updateProviderModel(provider: string, model: string): void;
18
+ getSessionInfo(): {
19
+ id: string;
20
+ startTime: number;
21
+ provider: string;
22
+ model: string;
23
+ };
24
+ }
25
+ export declare function initializeSession(provider: string, model: string): void;
26
+ export declare function getCurrentSession(): SessionTracker | null;
27
+ export declare function clearCurrentSession(): void;
28
+ //# sourceMappingURL=tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../source/usage/tracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,sBAAsB,CAAC;AAIpD,OAAO,KAAK,EAAe,mBAAmB,EAAC,MAAM,gBAAgB,CAAC;AAEtE,qBAAa,cAAc;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAS;gBAEV,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAO3C,OAAO,CAAC,iBAAiB;IAInB,eAAe,CACpB,QAAQ,EAAE,OAAO,EAAE,EACnB,SAAS,EAAE,SAAS,GAClB,OAAO,CAAC,mBAAmB,CAAC;IAkB/B,WAAW,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAiB5D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1D,cAAc,IAAI;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACd;CAQD;AAID,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAEvE;AAED,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Usage tracker
3
+ * Tracks current session usage
4
+ */
5
+ import { calculateTokenBreakdown } from './calculator.js';
6
+ import { addSession } from './storage.js';
7
+ import { getModelContextLimit } from '../models/index.js';
8
+ export class SessionTracker {
9
+ sessionId;
10
+ startTime;
11
+ provider;
12
+ model;
13
+ constructor(provider, model) {
14
+ this.sessionId = this.generateSessionId();
15
+ this.startTime = Date.now();
16
+ this.provider = provider;
17
+ this.model = model;
18
+ }
19
+ generateSessionId() {
20
+ return `${Date.now()}-${Math.random().toString(36).substring(7)}`;
21
+ }
22
+ async getCurrentStats(messages, tokenizer) {
23
+ const breakdown = calculateTokenBreakdown(messages, tokenizer);
24
+ const contextLimit = await getModelContextLimit(this.model);
25
+ const percentUsed = contextLimit
26
+ ? (breakdown.total / contextLimit) * 100
27
+ : 0;
28
+ return {
29
+ tokens: breakdown,
30
+ messageCount: messages.length,
31
+ startTime: this.startTime,
32
+ provider: this.provider,
33
+ model: this.model,
34
+ contextLimit,
35
+ percentUsed,
36
+ };
37
+ }
38
+ saveSession(messages, tokenizer) {
39
+ const breakdown = calculateTokenBreakdown(messages, tokenizer);
40
+ const duration = Date.now() - this.startTime;
41
+ const session = {
42
+ id: this.sessionId,
43
+ timestamp: this.startTime,
44
+ provider: this.provider,
45
+ model: this.model,
46
+ tokens: breakdown,
47
+ messageCount: messages.length,
48
+ duration,
49
+ };
50
+ addSession(session);
51
+ }
52
+ updateProviderModel(provider, model) {
53
+ this.provider = provider;
54
+ this.model = model;
55
+ }
56
+ getSessionInfo() {
57
+ return {
58
+ id: this.sessionId,
59
+ startTime: this.startTime,
60
+ provider: this.provider,
61
+ model: this.model,
62
+ };
63
+ }
64
+ }
65
+ let currentSessionTracker = null;
66
+ export function initializeSession(provider, model) {
67
+ currentSessionTracker = new SessionTracker(provider, model);
68
+ }
69
+ export function getCurrentSession() {
70
+ return currentSessionTracker;
71
+ }
72
+ export function clearCurrentSession() {
73
+ currentSessionTracker = null;
74
+ }
75
+ //# sourceMappingURL=tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../source/usage/tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tracker.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.spec.d.ts","sourceRoot":"","sources":["../../source/usage/tracker.spec.ts"],"names":[],"mappings":""}