@ank1015/providers 0.0.1 → 0.0.2

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 (169) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -383
  3. package/dist/agent/conversation.d.ts +97 -0
  4. package/dist/agent/conversation.d.ts.map +1 -0
  5. package/dist/agent/conversation.js +328 -0
  6. package/dist/agent/conversation.js.map +1 -0
  7. package/dist/agent/runner.d.ts +37 -0
  8. package/dist/agent/runner.d.ts.map +1 -0
  9. package/dist/agent/runner.js +169 -0
  10. package/dist/agent/runner.js.map +1 -0
  11. package/dist/agent/tools/calculate.d.ts +15 -0
  12. package/dist/agent/tools/calculate.d.ts.map +1 -0
  13. package/dist/agent/tools/calculate.js +23 -0
  14. package/dist/agent/tools/calculate.js.map +1 -0
  15. package/dist/agent/tools/get-current-time.d.ts +15 -0
  16. package/dist/agent/tools/get-current-time.d.ts.map +1 -0
  17. package/dist/agent/tools/get-current-time.js +38 -0
  18. package/dist/agent/tools/get-current-time.js.map +1 -0
  19. package/dist/agent/tools/index.d.ts +3 -0
  20. package/dist/agent/tools/index.d.ts.map +1 -0
  21. package/dist/agent/tools/index.js +3 -0
  22. package/dist/agent/tools/index.js.map +1 -0
  23. package/dist/agent/types.d.ts +53 -31
  24. package/dist/agent/types.d.ts.map +1 -1
  25. package/dist/agent/types.js +1 -2
  26. package/dist/agent/utils.d.ts +14 -0
  27. package/dist/agent/utils.d.ts.map +1 -0
  28. package/dist/agent/utils.js +59 -0
  29. package/dist/agent/utils.js.map +1 -0
  30. package/dist/index.d.ts +16 -9
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +16 -28
  33. package/dist/index.js.map +1 -1
  34. package/dist/llm.d.ts +15 -0
  35. package/dist/llm.d.ts.map +1 -0
  36. package/dist/llm.js +92 -0
  37. package/dist/llm.js.map +1 -0
  38. package/dist/models.d.ts +8 -1
  39. package/dist/models.d.ts.map +1 -1
  40. package/dist/models.generated.d.ts +25 -112
  41. package/dist/models.generated.d.ts.map +1 -1
  42. package/dist/models.generated.js +72 -227
  43. package/dist/models.generated.js.map +1 -1
  44. package/dist/models.js +30 -32
  45. package/dist/models.js.map +1 -1
  46. package/dist/providers/google/complete.d.ts +3 -0
  47. package/dist/providers/google/complete.d.ts.map +1 -0
  48. package/dist/providers/google/complete.js +53 -0
  49. package/dist/providers/google/complete.js.map +1 -0
  50. package/dist/providers/google/index.d.ts +6 -0
  51. package/dist/providers/google/index.d.ts.map +1 -0
  52. package/dist/providers/google/index.js +6 -0
  53. package/dist/providers/google/index.js.map +1 -0
  54. package/dist/providers/google/stream.d.ts +3 -0
  55. package/dist/providers/google/stream.d.ts.map +1 -0
  56. package/dist/providers/{google.js → google/stream.js} +67 -231
  57. package/dist/providers/google/stream.js.map +1 -0
  58. package/dist/providers/google/types.d.ts +8 -0
  59. package/dist/providers/google/types.d.ts.map +1 -0
  60. package/dist/providers/google/types.js +2 -0
  61. package/dist/providers/google/types.js.map +1 -0
  62. package/dist/providers/google/utils.d.ts +30 -0
  63. package/dist/providers/google/utils.d.ts.map +1 -0
  64. package/dist/providers/google/utils.js +354 -0
  65. package/dist/providers/google/utils.js.map +1 -0
  66. package/dist/providers/openai/complete.d.ts +3 -0
  67. package/dist/providers/openai/complete.d.ts.map +1 -0
  68. package/dist/providers/openai/complete.js +57 -0
  69. package/dist/providers/openai/complete.js.map +1 -0
  70. package/dist/providers/openai/index.d.ts +4 -0
  71. package/dist/providers/openai/index.d.ts.map +1 -0
  72. package/dist/providers/openai/index.js +4 -0
  73. package/dist/providers/openai/index.js.map +1 -0
  74. package/dist/providers/openai/stream.d.ts +3 -0
  75. package/dist/providers/openai/stream.d.ts.map +1 -0
  76. package/dist/providers/{openai.js → openai/stream.js} +74 -152
  77. package/dist/providers/openai/stream.js.map +1 -0
  78. package/dist/providers/openai/types.d.ts +8 -0
  79. package/dist/providers/openai/types.d.ts.map +1 -0
  80. package/dist/providers/openai/types.js +2 -0
  81. package/dist/providers/openai/types.js.map +1 -0
  82. package/dist/providers/openai/utils.d.ts +13 -0
  83. package/dist/providers/openai/utils.d.ts.map +1 -0
  84. package/dist/providers/openai/utils.js +285 -0
  85. package/dist/providers/openai/utils.js.map +1 -0
  86. package/dist/types.d.ts +95 -87
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js +1 -9
  89. package/dist/types.js.map +1 -1
  90. package/dist/utils/event-stream.d.ts +2 -2
  91. package/dist/utils/event-stream.d.ts.map +1 -1
  92. package/dist/utils/event-stream.js +2 -7
  93. package/dist/utils/event-stream.js.map +1 -1
  94. package/dist/utils/json-parse.js +3 -6
  95. package/dist/utils/json-parse.js.map +1 -1
  96. package/dist/utils/overflow.d.ts +51 -0
  97. package/dist/utils/overflow.d.ts.map +1 -0
  98. package/dist/utils/overflow.js +106 -0
  99. package/dist/utils/overflow.js.map +1 -0
  100. package/dist/utils/sanitize-unicode.js +1 -4
  101. package/dist/utils/sanitize-unicode.js.map +1 -1
  102. package/dist/utils/uuid.d.ts +6 -0
  103. package/dist/utils/uuid.d.ts.map +1 -0
  104. package/dist/utils/uuid.js +9 -0
  105. package/dist/utils/uuid.js.map +1 -0
  106. package/dist/utils/validation.d.ts +10 -3
  107. package/dist/utils/validation.d.ts.map +1 -1
  108. package/dist/utils/validation.js +20 -12
  109. package/dist/utils/validation.js.map +1 -1
  110. package/package.json +45 -8
  111. package/biome.json +0 -43
  112. package/dist/agent/agent-loop.d.ts +0 -5
  113. package/dist/agent/agent-loop.d.ts.map +0 -1
  114. package/dist/agent/agent-loop.js +0 -219
  115. package/dist/agent/agent-loop.js.map +0 -1
  116. package/dist/providers/convert.d.ts +0 -6
  117. package/dist/providers/convert.d.ts.map +0 -1
  118. package/dist/providers/convert.js +0 -207
  119. package/dist/providers/convert.js.map +0 -1
  120. package/dist/providers/google.d.ts +0 -26
  121. package/dist/providers/google.d.ts.map +0 -1
  122. package/dist/providers/google.js.map +0 -1
  123. package/dist/providers/openai.d.ts +0 -17
  124. package/dist/providers/openai.d.ts.map +0 -1
  125. package/dist/providers/openai.js.map +0 -1
  126. package/dist/stream.d.ts +0 -4
  127. package/dist/stream.d.ts.map +0 -1
  128. package/dist/stream.js +0 -40
  129. package/dist/stream.js.map +0 -1
  130. package/dist/test-google-agent-loop.d.ts +0 -2
  131. package/dist/test-google-agent-loop.d.ts.map +0 -1
  132. package/dist/test-google-agent-loop.js +0 -186
  133. package/dist/test-google-agent-loop.js.map +0 -1
  134. package/dist/test-google.d.ts +0 -2
  135. package/dist/test-google.d.ts.map +0 -1
  136. package/dist/test-google.js +0 -41
  137. package/dist/test-google.js.map +0 -1
  138. package/src/agent/agent-loop.ts +0 -275
  139. package/src/agent/types.ts +0 -80
  140. package/src/index.ts +0 -72
  141. package/src/models.generated.ts +0 -314
  142. package/src/models.ts +0 -45
  143. package/src/providers/convert.ts +0 -222
  144. package/src/providers/google.ts +0 -496
  145. package/src/providers/openai.ts +0 -437
  146. package/src/stream.ts +0 -60
  147. package/src/types.ts +0 -198
  148. package/src/utils/event-stream.ts +0 -60
  149. package/src/utils/json-parse.ts +0 -28
  150. package/src/utils/sanitize-unicode.ts +0 -25
  151. package/src/utils/validation.ts +0 -69
  152. package/test/core/agent-loop.test.ts +0 -958
  153. package/test/core/stream.test.ts +0 -409
  154. package/test/data/red-circle.png +0 -0
  155. package/test/data/superintelligentwill.pdf +0 -0
  156. package/test/edge-cases/general.test.ts +0 -565
  157. package/test/integration/e2e.test.ts +0 -530
  158. package/test/models/cost.test.ts +0 -499
  159. package/test/models/registry.test.ts +0 -298
  160. package/test/providers/convert.test.ts +0 -846
  161. package/test/providers/google-schema.test.ts +0 -666
  162. package/test/providers/google-stream.test.ts +0 -369
  163. package/test/providers/openai-stream.test.ts +0 -251
  164. package/test/utils/event-stream.test.ts +0 -289
  165. package/test/utils/json-parse.test.ts +0 -344
  166. package/test/utils/sanitize-unicode.test.ts +0 -329
  167. package/test/utils/validation.test.ts +0 -614
  168. package/tsconfig.json +0 -21
  169. package/vitest.config.ts +0 -9
@@ -1,499 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { calculateCost } from '../../src/models';
3
- import { Model, Usage } from '../../src/types';
4
-
5
- const mockModel: Model<'openai'> = {
6
- id: 'test-model',
7
- name: 'Test Model',
8
- api: 'openai',
9
- baseUrl: 'https://api.openai.com',
10
- reasoning: false,
11
- input: ['text'],
12
- cost: {
13
- input: 0.15, // $0.15 per million tokens
14
- output: 0.60, // $0.60 per million tokens
15
- cacheRead: 0.015, // $0.015 per million tokens
16
- cacheWrite: 0.30, // $0.30 per million tokens
17
- },
18
- contextWindow: 128000,
19
- maxTokens: 4096,
20
- };
21
-
22
- describe('calculateCost', () => {
23
- describe('Basic calculations', () => {
24
- it('should calculate input token cost', () => {
25
- const usage: Usage = {
26
- input: 1000,
27
- output: 0,
28
- cacheRead: 0,
29
- cacheWrite: 0,
30
- totalTokens: 1000,
31
- cost: {
32
- input: 0,
33
- output: 0,
34
- cacheRead: 0,
35
- cacheWrite: 0,
36
- total: 0,
37
- },
38
- };
39
-
40
- calculateCost(mockModel, usage);
41
-
42
- // 1000 tokens * ($0.15 / 1,000,000) = $0.00015
43
- expect(usage.cost.input).toBeCloseTo(0.00015, 10);
44
- expect(usage.cost.total).toBeCloseTo(0.00015, 10);
45
- });
46
-
47
- it('should calculate output token cost', () => {
48
- const usage: Usage = {
49
- input: 0,
50
- output: 500,
51
- cacheRead: 0,
52
- cacheWrite: 0,
53
- totalTokens: 500,
54
- cost: {
55
- input: 0,
56
- output: 0,
57
- cacheRead: 0,
58
- cacheWrite: 0,
59
- total: 0,
60
- },
61
- };
62
-
63
- calculateCost(mockModel, usage);
64
-
65
- // 500 tokens * ($0.60 / 1,000,000) = $0.0003
66
- expect(usage.cost.output).toBeCloseTo(0.0003, 10);
67
- expect(usage.cost.total).toBeCloseTo(0.0003, 10);
68
- });
69
-
70
- it('should calculate cache read token cost', () => {
71
- const usage: Usage = {
72
- input: 0,
73
- output: 0,
74
- cacheRead: 10000,
75
- cacheWrite: 0,
76
- totalTokens: 10000,
77
- cost: {
78
- input: 0,
79
- output: 0,
80
- cacheRead: 0,
81
- cacheWrite: 0,
82
- total: 0,
83
- },
84
- };
85
-
86
- calculateCost(mockModel, usage);
87
-
88
- // 10000 tokens * ($0.015 / 1,000,000) = $0.00015
89
- expect(usage.cost.cacheRead).toBeCloseTo(0.00015, 10);
90
- expect(usage.cost.total).toBeCloseTo(0.00015, 10);
91
- });
92
-
93
- it('should calculate cache write token cost', () => {
94
- const usage: Usage = {
95
- input: 0,
96
- output: 0,
97
- cacheRead: 0,
98
- cacheWrite: 5000,
99
- totalTokens: 5000,
100
- cost: {
101
- input: 0,
102
- output: 0,
103
- cacheRead: 0,
104
- cacheWrite: 0,
105
- total: 0,
106
- },
107
- };
108
-
109
- calculateCost(mockModel, usage);
110
-
111
- // 5000 tokens * ($0.30 / 1,000,000) = $0.0015
112
- expect(usage.cost.cacheWrite).toBeCloseTo(0.0015, 10);
113
- expect(usage.cost.total).toBeCloseTo(0.0015, 10);
114
- });
115
- });
116
-
117
- describe('Combined calculations', () => {
118
- it('should calculate total cost for all token types', () => {
119
- const usage: Usage = {
120
- input: 1000,
121
- output: 500,
122
- cacheRead: 2000,
123
- cacheWrite: 1000,
124
- totalTokens: 4500,
125
- cost: {
126
- input: 0,
127
- output: 0,
128
- cacheRead: 0,
129
- cacheWrite: 0,
130
- total: 0,
131
- },
132
- };
133
-
134
- calculateCost(mockModel, usage);
135
-
136
- // Input: 1000 * 0.15 / 1M = 0.00015
137
- // Output: 500 * 0.60 / 1M = 0.0003
138
- // Cache Read: 2000 * 0.015 / 1M = 0.00003
139
- // Cache Write: 1000 * 0.30 / 1M = 0.0003
140
- // Total: 0.00015 + 0.0003 + 0.00003 + 0.0003 = 0.00078
141
- expect(usage.cost.input).toBeCloseTo(0.00015, 10);
142
- expect(usage.cost.output).toBeCloseTo(0.0003, 10);
143
- expect(usage.cost.cacheRead).toBeCloseTo(0.00003, 10);
144
- expect(usage.cost.cacheWrite).toBeCloseTo(0.0003, 10);
145
- expect(usage.cost.total).toBeCloseTo(0.00078, 10);
146
- });
147
-
148
- it('should calculate cost for typical conversation', () => {
149
- const usage: Usage = {
150
- input: 5000,
151
- output: 2000,
152
- cacheRead: 0,
153
- cacheWrite: 0,
154
- totalTokens: 7000,
155
- cost: {
156
- input: 0,
157
- output: 0,
158
- cacheRead: 0,
159
- cacheWrite: 0,
160
- total: 0,
161
- },
162
- };
163
-
164
- calculateCost(mockModel, usage);
165
-
166
- expect(usage.cost.total).toBeCloseTo(0.00195, 10);
167
- });
168
-
169
- it('should calculate cost with caching enabled', () => {
170
- const usage: Usage = {
171
- input: 1000,
172
- output: 500,
173
- cacheRead: 10000, // Most context from cache
174
- cacheWrite: 1000, // New context cached
175
- totalTokens: 12500,
176
- cost: {
177
- input: 0,
178
- output: 0,
179
- cacheRead: 0,
180
- cacheWrite: 0,
181
- total: 0,
182
- },
183
- };
184
-
185
- calculateCost(mockModel, usage);
186
-
187
- // Cache read rate per token should be cheaper than input rate per token
188
- const cacheReadPerToken = usage.cost.cacheRead / usage.cacheRead;
189
- const inputPerToken = usage.cost.input / usage.input;
190
- expect(cacheReadPerToken).toBeLessThan(inputPerToken);
191
-
192
- // Total should be much cheaper than if all 12500 were input tokens
193
- const allInputCost = (12500 * mockModel.cost.input) / 1000000;
194
- expect(usage.cost.total).toBeLessThan(allInputCost);
195
- });
196
- });
197
-
198
- describe('Zero token cases', () => {
199
- it('should return zero cost for zero tokens', () => {
200
- const usage: Usage = {
201
- input: 0,
202
- output: 0,
203
- cacheRead: 0,
204
- cacheWrite: 0,
205
- totalTokens: 0,
206
- cost: {
207
- input: 0,
208
- output: 0,
209
- cacheRead: 0,
210
- cacheWrite: 0,
211
- total: 0,
212
- },
213
- };
214
-
215
- calculateCost(mockModel, usage);
216
-
217
- expect(usage.cost.input).toBe(0);
218
- expect(usage.cost.output).toBe(0);
219
- expect(usage.cost.cacheRead).toBe(0);
220
- expect(usage.cost.cacheWrite).toBe(0);
221
- expect(usage.cost.total).toBe(0);
222
- });
223
-
224
- it('should handle zero cost model', () => {
225
- const freeModel: Model<'openai'> = {
226
- ...mockModel,
227
- cost: {
228
- input: 0,
229
- output: 0,
230
- cacheRead: 0,
231
- cacheWrite: 0,
232
- },
233
- };
234
-
235
- const usage: Usage = {
236
- input: 10000,
237
- output: 5000,
238
- cacheRead: 0,
239
- cacheWrite: 0,
240
- totalTokens: 15000,
241
- cost: {
242
- input: 0,
243
- output: 0,
244
- cacheRead: 0,
245
- cacheWrite: 0,
246
- total: 0,
247
- },
248
- };
249
-
250
- calculateCost(freeModel, usage);
251
-
252
- expect(usage.cost.total).toBe(0);
253
- });
254
- });
255
-
256
- describe('High token counts', () => {
257
- it('should accurately calculate cost for large token counts', () => {
258
- const usage: Usage = {
259
- input: 100000, // 100k tokens
260
- output: 50000, // 50k tokens
261
- cacheRead: 0,
262
- cacheWrite: 0,
263
- totalTokens: 150000,
264
- cost: {
265
- input: 0,
266
- output: 0,
267
- cacheRead: 0,
268
- cacheWrite: 0,
269
- total: 0,
270
- },
271
- };
272
-
273
- calculateCost(mockModel, usage);
274
-
275
- // Input: 100000 * 0.15 / 1M = 0.015
276
- // Output: 50000 * 0.60 / 1M = 0.03
277
- // Total: 0.045
278
- expect(usage.cost.input).toBeCloseTo(0.015, 10);
279
- expect(usage.cost.output).toBeCloseTo(0.03, 10);
280
- expect(usage.cost.total).toBeCloseTo(0.045, 10);
281
- });
282
-
283
- it('should handle million+ token counts', () => {
284
- const usage: Usage = {
285
- input: 2000000, // 2 million tokens
286
- output: 1000000, // 1 million tokens
287
- cacheRead: 0,
288
- cacheWrite: 0,
289
- totalTokens: 3000000,
290
- cost: {
291
- input: 0,
292
- output: 0,
293
- cacheRead: 0,
294
- cacheWrite: 0,
295
- total: 0,
296
- },
297
- };
298
-
299
- calculateCost(mockModel, usage);
300
-
301
- // Input: 2M * 0.15 / 1M = 0.30
302
- // Output: 1M * 0.60 / 1M = 0.60
303
- // Total: 0.90
304
- expect(usage.cost.input).toBeCloseTo(0.30, 10);
305
- expect(usage.cost.output).toBeCloseTo(0.60, 10);
306
- expect(usage.cost.total).toBeCloseTo(0.90, 10);
307
- });
308
- });
309
-
310
- describe('Different model pricing', () => {
311
- it('should calculate cost for expensive model', () => {
312
- const expensiveModel: Model<'openai'> = {
313
- ...mockModel,
314
- cost: {
315
- input: 5.00, // $5 per million
316
- output: 15.00, // $15 per million
317
- cacheRead: 0.50,
318
- cacheWrite: 2.50,
319
- },
320
- };
321
-
322
- const usage: Usage = {
323
- input: 1000,
324
- output: 1000,
325
- cacheRead: 0,
326
- cacheWrite: 0,
327
- totalTokens: 2000,
328
- cost: {
329
- input: 0,
330
- output: 0,
331
- cacheRead: 0,
332
- cacheWrite: 0,
333
- total: 0,
334
- },
335
- };
336
-
337
- calculateCost(expensiveModel, usage);
338
-
339
- // Input: 1000 * 5 / 1M = 0.005
340
- // Output: 1000 * 15 / 1M = 0.015
341
- // Total: 0.02
342
- expect(usage.cost.total).toBeCloseTo(0.02, 10);
343
- });
344
-
345
- it('should calculate cost for cheap model', () => {
346
- const cheapModel: Model<'openai'> = {
347
- ...mockModel,
348
- cost: {
349
- input: 0.01, // $0.01 per million
350
- output: 0.03, // $0.03 per million
351
- cacheRead: 0.001,
352
- cacheWrite: 0.005,
353
- },
354
- };
355
-
356
- const usage: Usage = {
357
- input: 10000,
358
- output: 10000,
359
- cacheRead: 0,
360
- cacheWrite: 0,
361
- totalTokens: 20000,
362
- cost: {
363
- input: 0,
364
- output: 0,
365
- cacheRead: 0,
366
- cacheWrite: 0,
367
- total: 0,
368
- },
369
- };
370
-
371
- calculateCost(cheapModel, usage);
372
-
373
- // Input: 10000 * 0.01 / 1M = 0.0001
374
- // Output: 10000 * 0.03 / 1M = 0.0003
375
- // Total: 0.0004
376
- expect(usage.cost.total).toBeCloseTo(0.0004, 10);
377
- });
378
- });
379
-
380
- describe('Floating point precision', () => {
381
- it('should maintain precision for very small costs', () => {
382
- const usage: Usage = {
383
- input: 1, // Single token
384
- output: 1,
385
- cacheRead: 0,
386
- cacheWrite: 0,
387
- totalTokens: 2,
388
- cost: {
389
- input: 0,
390
- output: 0,
391
- cacheRead: 0,
392
- cacheWrite: 0,
393
- total: 0,
394
- },
395
- };
396
-
397
- calculateCost(mockModel, usage);
398
-
399
- // Should have meaningful non-zero values
400
- expect(usage.cost.input).toBeGreaterThan(0);
401
- expect(usage.cost.output).toBeGreaterThan(0);
402
- expect(usage.cost.total).toBeGreaterThan(0);
403
- });
404
-
405
- it('should handle fractional tokens (if they exist)', () => {
406
- const usage: Usage = {
407
- input: 1.5,
408
- output: 2.7,
409
- cacheRead: 0,
410
- cacheWrite: 0,
411
- totalTokens: 4.2,
412
- cost: {
413
- input: 0,
414
- output: 0,
415
- cacheRead: 0,
416
- cacheWrite: 0,
417
- total: 0,
418
- },
419
- };
420
-
421
- calculateCost(mockModel, usage);
422
-
423
- expect(usage.cost.total).toBeGreaterThan(0);
424
- expect(Number.isFinite(usage.cost.total)).toBe(true);
425
- });
426
- });
427
-
428
- describe('Per-million token rate conversion', () => {
429
- it('should correctly convert per-million rates to actual costs', () => {
430
- const usage: Usage = {
431
- input: 1000000, // Exactly 1 million tokens
432
- output: 0,
433
- cacheRead: 0,
434
- cacheWrite: 0,
435
- totalTokens: 1000000,
436
- cost: {
437
- input: 0,
438
- output: 0,
439
- cacheRead: 0,
440
- cacheWrite: 0,
441
- total: 0,
442
- },
443
- };
444
-
445
- calculateCost(mockModel, usage);
446
-
447
- // Should equal the per-million rate
448
- expect(usage.cost.input).toBeCloseTo(mockModel.cost.input, 10);
449
- });
450
-
451
- it('should calculate half-million tokens correctly', () => {
452
- const usage: Usage = {
453
- input: 500000, // Half million tokens
454
- output: 0,
455
- cacheRead: 0,
456
- cacheWrite: 0,
457
- totalTokens: 500000,
458
- cost: {
459
- input: 0,
460
- output: 0,
461
- cacheRead: 0,
462
- cacheWrite: 0,
463
- total: 0,
464
- },
465
- };
466
-
467
- calculateCost(mockModel, usage);
468
-
469
- // Should be half the per-million rate
470
- expect(usage.cost.input).toBeCloseTo(mockModel.cost.input / 2, 10);
471
- });
472
- });
473
-
474
- describe('Cost mutation', () => {
475
- it('should mutate the usage object in place', () => {
476
- const usage: Usage = {
477
- input: 1000,
478
- output: 500,
479
- cacheRead: 0,
480
- cacheWrite: 0,
481
- totalTokens: 1500,
482
- cost: {
483
- input: 0,
484
- output: 0,
485
- cacheRead: 0,
486
- cacheWrite: 0,
487
- total: 0,
488
- },
489
- };
490
-
491
- const originalUsage = usage;
492
- calculateCost(mockModel, usage);
493
-
494
- // Should mutate the same object
495
- expect(usage).toBe(originalUsage);
496
- expect(usage.cost.total).toBeGreaterThan(0);
497
- });
498
- });
499
- });