agent-duelist 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,2207 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ anthropic: () => anthropic,
34
+ azureOpenai: () => azureOpenai,
35
+ consoleReporter: () => consoleReporter,
36
+ defineArena: () => defineArena,
37
+ gemini: () => gemini,
38
+ jsonReporter: () => jsonReporter,
39
+ openai: () => openai,
40
+ openaiCompatible: () => openaiCompatible,
41
+ registerPricing: () => registerPricing
42
+ });
43
+ module.exports = __toCommonJS(index_exports);
44
+
45
+ // src/scorers/latency.ts
46
+ var MIN_MS = 500;
47
+ var MAX_MS = 1e4;
48
+ var latencyScorer = ({ result }) => {
49
+ const clamped = Math.max(MIN_MS, Math.min(MAX_MS, result.latencyMs));
50
+ const value = 1 - (clamped - MIN_MS) / (MAX_MS - MIN_MS);
51
+ return {
52
+ name: "latency",
53
+ value: Math.round(value * 100) / 100,
54
+ details: { ms: result.latencyMs }
55
+ };
56
+ };
57
+
58
+ // src/pricing/catalog.json
59
+ var catalog_default = {
60
+ _meta: {
61
+ source: "OpenRouter API \u2014 all providers (https://openrouter.ai/api/v1/models)",
62
+ updatedAt: "2026-02-28",
63
+ unit: "USD per token"
64
+ },
65
+ models: {
66
+ "ai21/jamba-large-1.7": {
67
+ inputPerToken: 2e-6,
68
+ outputPerToken: 8e-6
69
+ },
70
+ "aion-labs/aion-1.0": {
71
+ inputPerToken: 4e-6,
72
+ outputPerToken: 8e-6
73
+ },
74
+ "aion-labs/aion-1.0-mini": {
75
+ inputPerToken: 7e-7,
76
+ outputPerToken: 14e-7
77
+ },
78
+ "aion-labs/aion-2.0": {
79
+ inputPerToken: 8e-7,
80
+ outputPerToken: 16e-7
81
+ },
82
+ "aion-labs/aion-rp-llama-3.1-8b": {
83
+ inputPerToken: 8e-7,
84
+ outputPerToken: 16e-7
85
+ },
86
+ "alfredpros/codellama-7b-instruct-solidity": {
87
+ inputPerToken: 8e-7,
88
+ outputPerToken: 12e-7
89
+ },
90
+ "alibaba/tongyi-deepresearch-30b-a3b": {
91
+ inputPerToken: 9e-8,
92
+ outputPerToken: 45e-8
93
+ },
94
+ "allenai/molmo-2-8b": {
95
+ inputPerToken: 2e-7,
96
+ outputPerToken: 2e-7
97
+ },
98
+ "allenai/olmo-2-0325-32b-instruct": {
99
+ inputPerToken: 5e-8,
100
+ outputPerToken: 2e-7
101
+ },
102
+ "allenai/olmo-3-32b-think": {
103
+ inputPerToken: 15e-8,
104
+ outputPerToken: 5e-7
105
+ },
106
+ "allenai/olmo-3-7b-instruct": {
107
+ inputPerToken: 1e-7,
108
+ outputPerToken: 2e-7
109
+ },
110
+ "allenai/olmo-3-7b-think": {
111
+ inputPerToken: 12e-8,
112
+ outputPerToken: 2e-7
113
+ },
114
+ "allenai/olmo-3.1-32b-instruct": {
115
+ inputPerToken: 2e-7,
116
+ outputPerToken: 6e-7
117
+ },
118
+ "alpindale/goliath-120b": {
119
+ inputPerToken: 375e-8,
120
+ outputPerToken: 75e-7
121
+ },
122
+ "amazon/nova-2-lite-v1": {
123
+ inputPerToken: 3e-7,
124
+ outputPerToken: 25e-7
125
+ },
126
+ "amazon/nova-lite-v1": {
127
+ inputPerToken: 6e-8,
128
+ outputPerToken: 24e-8
129
+ },
130
+ "amazon/nova-micro-v1": {
131
+ inputPerToken: 35e-9,
132
+ outputPerToken: 14e-8
133
+ },
134
+ "amazon/nova-premier-v1": {
135
+ inputPerToken: 25e-7,
136
+ outputPerToken: 125e-7
137
+ },
138
+ "amazon/nova-pro-v1": {
139
+ inputPerToken: 8e-7,
140
+ outputPerToken: 32e-7
141
+ },
142
+ "anthracite-org/magnum-v4-72b": {
143
+ inputPerToken: 3e-6,
144
+ outputPerToken: 5e-6
145
+ },
146
+ "anthropic/claude-3-haiku": {
147
+ inputPerToken: 25e-8,
148
+ outputPerToken: 125e-8
149
+ },
150
+ "anthropic/claude-3.5-haiku": {
151
+ inputPerToken: 8e-7,
152
+ outputPerToken: 4e-6
153
+ },
154
+ "anthropic/claude-3.5-sonnet": {
155
+ inputPerToken: 6e-6,
156
+ outputPerToken: 3e-5
157
+ },
158
+ "anthropic/claude-3.7-sonnet": {
159
+ inputPerToken: 3e-6,
160
+ outputPerToken: 15e-6
161
+ },
162
+ "anthropic/claude-3.7-sonnet:thinking": {
163
+ inputPerToken: 3e-6,
164
+ outputPerToken: 15e-6
165
+ },
166
+ "anthropic/claude-haiku-4.5": {
167
+ inputPerToken: 1e-6,
168
+ outputPerToken: 5e-6
169
+ },
170
+ "anthropic/claude-opus-4": {
171
+ inputPerToken: 15e-6,
172
+ outputPerToken: 75e-6
173
+ },
174
+ "anthropic/claude-opus-4.1": {
175
+ inputPerToken: 15e-6,
176
+ outputPerToken: 75e-6
177
+ },
178
+ "anthropic/claude-opus-4.5": {
179
+ inputPerToken: 5e-6,
180
+ outputPerToken: 25e-6
181
+ },
182
+ "anthropic/claude-opus-4.6": {
183
+ inputPerToken: 5e-6,
184
+ outputPerToken: 25e-6
185
+ },
186
+ "anthropic/claude-sonnet-4": {
187
+ inputPerToken: 3e-6,
188
+ outputPerToken: 15e-6
189
+ },
190
+ "anthropic/claude-sonnet-4.5": {
191
+ inputPerToken: 3e-6,
192
+ outputPerToken: 15e-6
193
+ },
194
+ "anthropic/claude-sonnet-4.6": {
195
+ inputPerToken: 3e-6,
196
+ outputPerToken: 15e-6
197
+ },
198
+ "arcee-ai/coder-large": {
199
+ inputPerToken: 5e-7,
200
+ outputPerToken: 8e-7
201
+ },
202
+ "arcee-ai/maestro-reasoning": {
203
+ inputPerToken: 9e-7,
204
+ outputPerToken: 33e-7
205
+ },
206
+ "arcee-ai/spotlight": {
207
+ inputPerToken: 18e-8,
208
+ outputPerToken: 18e-8
209
+ },
210
+ "arcee-ai/trinity-mini": {
211
+ inputPerToken: 45e-9,
212
+ outputPerToken: 15e-8
213
+ },
214
+ "arcee-ai/virtuoso-large": {
215
+ inputPerToken: 75e-8,
216
+ outputPerToken: 12e-7
217
+ },
218
+ "baidu/ernie-4.5-21b-a3b": {
219
+ inputPerToken: 7e-8,
220
+ outputPerToken: 28e-8
221
+ },
222
+ "baidu/ernie-4.5-21b-a3b-thinking": {
223
+ inputPerToken: 7e-8,
224
+ outputPerToken: 28e-8
225
+ },
226
+ "baidu/ernie-4.5-300b-a47b": {
227
+ inputPerToken: 28e-8,
228
+ outputPerToken: 11e-7
229
+ },
230
+ "baidu/ernie-4.5-vl-28b-a3b": {
231
+ inputPerToken: 14e-8,
232
+ outputPerToken: 56e-8
233
+ },
234
+ "baidu/ernie-4.5-vl-424b-a47b": {
235
+ inputPerToken: 42e-8,
236
+ outputPerToken: 125e-8
237
+ },
238
+ "bytedance/seed-1.6": {
239
+ inputPerToken: 25e-8,
240
+ outputPerToken: 2e-6
241
+ },
242
+ "bytedance/seed-1.6-flash": {
243
+ inputPerToken: 75e-9,
244
+ outputPerToken: 3e-7
245
+ },
246
+ "bytedance/seed-2.0-mini": {
247
+ inputPerToken: 1e-7,
248
+ outputPerToken: 4e-7
249
+ },
250
+ "bytedance/ui-tars-1.5-7b": {
251
+ inputPerToken: 1e-7,
252
+ outputPerToken: 2e-7
253
+ },
254
+ "cohere/command-a": {
255
+ inputPerToken: 25e-7,
256
+ outputPerToken: 1e-5
257
+ },
258
+ "cohere/command-r-08-2024": {
259
+ inputPerToken: 15e-8,
260
+ outputPerToken: 6e-7
261
+ },
262
+ "cohere/command-r-plus-08-2024": {
263
+ inputPerToken: 25e-7,
264
+ outputPerToken: 1e-5
265
+ },
266
+ "cohere/command-r7b-12-2024": {
267
+ inputPerToken: 375e-10,
268
+ outputPerToken: 15e-8
269
+ },
270
+ "deepcogito/cogito-v2.1-671b": {
271
+ inputPerToken: 125e-8,
272
+ outputPerToken: 125e-8
273
+ },
274
+ "deepseek/deepseek-chat": {
275
+ inputPerToken: 32e-8,
276
+ outputPerToken: 89e-8
277
+ },
278
+ "deepseek/deepseek-chat-v3-0324": {
279
+ inputPerToken: 2e-7,
280
+ outputPerToken: 77e-8
281
+ },
282
+ "deepseek/deepseek-chat-v3.1": {
283
+ inputPerToken: 15e-8,
284
+ outputPerToken: 75e-8
285
+ },
286
+ "deepseek/deepseek-r1": {
287
+ inputPerToken: 7e-7,
288
+ outputPerToken: 25e-7
289
+ },
290
+ "deepseek/deepseek-r1-0528": {
291
+ inputPerToken: 45e-8,
292
+ outputPerToken: 215e-8
293
+ },
294
+ "deepseek/deepseek-r1-distill-llama-70b": {
295
+ inputPerToken: 7e-7,
296
+ outputPerToken: 8e-7
297
+ },
298
+ "deepseek/deepseek-r1-distill-qwen-32b": {
299
+ inputPerToken: 29e-8,
300
+ outputPerToken: 29e-8
301
+ },
302
+ "deepseek/deepseek-v3": {
303
+ inputPerToken: 3e-7,
304
+ outputPerToken: 88e-8
305
+ },
306
+ "deepseek/deepseek-v3.1-terminus": {
307
+ inputPerToken: 21e-8,
308
+ outputPerToken: 79e-8
309
+ },
310
+ "deepseek/deepseek-v3.1-terminus:exacto": {
311
+ inputPerToken: 21e-8,
312
+ outputPerToken: 79e-8
313
+ },
314
+ "deepseek/deepseek-v3.2": {
315
+ inputPerToken: 25e-8,
316
+ outputPerToken: 4e-7
317
+ },
318
+ "deepseek/deepseek-v3.2-exp": {
319
+ inputPerToken: 27e-8,
320
+ outputPerToken: 41e-8
321
+ },
322
+ "deepseek/deepseek-v3.2-speciale": {
323
+ inputPerToken: 4e-7,
324
+ outputPerToken: 12e-7
325
+ },
326
+ "eleutherai/llemma_7b": {
327
+ inputPerToken: 8e-7,
328
+ outputPerToken: 12e-7
329
+ },
330
+ "essentialai/rnj-1-instruct": {
331
+ inputPerToken: 15e-8,
332
+ outputPerToken: 15e-8
333
+ },
334
+ "google/gemini-2.0-flash": {
335
+ inputPerToken: 1e-7,
336
+ outputPerToken: 4e-7
337
+ },
338
+ "google/gemini-2.0-flash-001": {
339
+ inputPerToken: 1e-7,
340
+ outputPerToken: 4e-7
341
+ },
342
+ "google/gemini-2.0-flash-lite-001": {
343
+ inputPerToken: 75e-9,
344
+ outputPerToken: 3e-7
345
+ },
346
+ "google/gemini-2.5-flash": {
347
+ inputPerToken: 3e-7,
348
+ outputPerToken: 25e-7
349
+ },
350
+ "google/gemini-2.5-flash-image": {
351
+ inputPerToken: 3e-7,
352
+ outputPerToken: 25e-7
353
+ },
354
+ "google/gemini-2.5-flash-lite": {
355
+ inputPerToken: 1e-7,
356
+ outputPerToken: 4e-7
357
+ },
358
+ "google/gemini-2.5-flash-lite-preview-09-2025": {
359
+ inputPerToken: 1e-7,
360
+ outputPerToken: 4e-7
361
+ },
362
+ "google/gemini-2.5-pro": {
363
+ inputPerToken: 125e-8,
364
+ outputPerToken: 1e-5
365
+ },
366
+ "google/gemini-2.5-pro-preview": {
367
+ inputPerToken: 125e-8,
368
+ outputPerToken: 1e-5
369
+ },
370
+ "google/gemini-2.5-pro-preview-05-06": {
371
+ inputPerToken: 125e-8,
372
+ outputPerToken: 1e-5
373
+ },
374
+ "google/gemini-3-flash-preview": {
375
+ inputPerToken: 5e-7,
376
+ outputPerToken: 3e-6
377
+ },
378
+ "google/gemini-3-pro-image-preview": {
379
+ inputPerToken: 2e-6,
380
+ outputPerToken: 12e-6
381
+ },
382
+ "google/gemini-3-pro-preview": {
383
+ inputPerToken: 2e-6,
384
+ outputPerToken: 12e-6
385
+ },
386
+ "google/gemini-3.1-flash-image-preview": {
387
+ inputPerToken: 25e-8,
388
+ outputPerToken: 15e-7
389
+ },
390
+ "google/gemini-3.1-pro-preview": {
391
+ inputPerToken: 2e-6,
392
+ outputPerToken: 12e-6
393
+ },
394
+ "google/gemini-3.1-pro-preview-customtools": {
395
+ inputPerToken: 2e-6,
396
+ outputPerToken: 12e-6
397
+ },
398
+ "google/gemma-2-27b-it": {
399
+ inputPerToken: 65e-8,
400
+ outputPerToken: 65e-8
401
+ },
402
+ "google/gemma-2-9b-it": {
403
+ inputPerToken: 3e-8,
404
+ outputPerToken: 9e-8
405
+ },
406
+ "google/gemma-3-12b-it": {
407
+ inputPerToken: 4e-8,
408
+ outputPerToken: 13e-8
409
+ },
410
+ "google/gemma-3-27b-it": {
411
+ inputPerToken: 4e-8,
412
+ outputPerToken: 15e-8
413
+ },
414
+ "google/gemma-3-4b-it": {
415
+ inputPerToken: 4e-8,
416
+ outputPerToken: 8e-8
417
+ },
418
+ "google/gemma-3n-e4b-it": {
419
+ inputPerToken: 2e-8,
420
+ outputPerToken: 4e-8
421
+ },
422
+ "gryphe/mythomax-l2-13b": {
423
+ inputPerToken: 6e-8,
424
+ outputPerToken: 6e-8
425
+ },
426
+ "ibm-granite/granite-4.0-h-micro": {
427
+ inputPerToken: 17e-9,
428
+ outputPerToken: 11e-8
429
+ },
430
+ "inception/mercury": {
431
+ inputPerToken: 25e-8,
432
+ outputPerToken: 1e-6
433
+ },
434
+ "inception/mercury-coder": {
435
+ inputPerToken: 25e-8,
436
+ outputPerToken: 1e-6
437
+ },
438
+ "inflection/inflection-3-pi": {
439
+ inputPerToken: 25e-7,
440
+ outputPerToken: 1e-5
441
+ },
442
+ "inflection/inflection-3-productivity": {
443
+ inputPerToken: 25e-7,
444
+ outputPerToken: 1e-5
445
+ },
446
+ "kwaipilot/kat-coder-pro": {
447
+ inputPerToken: 207e-9,
448
+ outputPerToken: 828e-9
449
+ },
450
+ "liquid/lfm-2-24b-a2b": {
451
+ inputPerToken: 3e-8,
452
+ outputPerToken: 12e-8
453
+ },
454
+ "liquid/lfm-2.2-6b": {
455
+ inputPerToken: 1e-8,
456
+ outputPerToken: 2e-8
457
+ },
458
+ "liquid/lfm2-8b-a1b": {
459
+ inputPerToken: 1e-8,
460
+ outputPerToken: 2e-8
461
+ },
462
+ "mancer/weaver": {
463
+ inputPerToken: 75e-8,
464
+ outputPerToken: 1e-6
465
+ },
466
+ "meituan/longcat-flash-chat": {
467
+ inputPerToken: 2e-7,
468
+ outputPerToken: 8e-7
469
+ },
470
+ "meta/llama-3-70b-instruct": {
471
+ inputPerToken: 51e-8,
472
+ outputPerToken: 74e-8
473
+ },
474
+ "meta/llama-3-8b-instruct": {
475
+ inputPerToken: 3e-8,
476
+ outputPerToken: 4e-8
477
+ },
478
+ "meta/llama-3.1-405b": {
479
+ inputPerToken: 4e-6,
480
+ outputPerToken: 4e-6
481
+ },
482
+ "meta/llama-3.1-405b-instruct": {
483
+ inputPerToken: 4e-6,
484
+ outputPerToken: 4e-6
485
+ },
486
+ "meta/llama-3.1-70b-instruct": {
487
+ inputPerToken: 4e-7,
488
+ outputPerToken: 4e-7
489
+ },
490
+ "meta/llama-3.1-8b-instruct": {
491
+ inputPerToken: 2e-8,
492
+ outputPerToken: 5e-8
493
+ },
494
+ "meta/llama-3.2-11b-vision-instruct": {
495
+ inputPerToken: 49e-9,
496
+ outputPerToken: 49e-9
497
+ },
498
+ "meta/llama-3.2-1b-instruct": {
499
+ inputPerToken: 27e-9,
500
+ outputPerToken: 2e-7
501
+ },
502
+ "meta/llama-3.2-3b-instruct": {
503
+ inputPerToken: 2e-8,
504
+ outputPerToken: 2e-8
505
+ },
506
+ "meta/llama-3.3-70b": {
507
+ inputPerToken: 12e-8,
508
+ outputPerToken: 3e-7
509
+ },
510
+ "meta/llama-3.3-70b-instruct": {
511
+ inputPerToken: 1e-7,
512
+ outputPerToken: 32e-8
513
+ },
514
+ "meta/llama-4-maverick": {
515
+ inputPerToken: 15e-8,
516
+ outputPerToken: 6e-7
517
+ },
518
+ "meta/llama-4-scout": {
519
+ inputPerToken: 8e-8,
520
+ outputPerToken: 3e-7
521
+ },
522
+ "meta/llama-guard-2-8b": {
523
+ inputPerToken: 2e-7,
524
+ outputPerToken: 2e-7
525
+ },
526
+ "meta/llama-guard-3-8b": {
527
+ inputPerToken: 2e-8,
528
+ outputPerToken: 6e-8
529
+ },
530
+ "meta/llama-guard-4-12b": {
531
+ inputPerToken: 18e-8,
532
+ outputPerToken: 18e-8
533
+ },
534
+ "microsoft/phi-4": {
535
+ inputPerToken: 6e-8,
536
+ outputPerToken: 14e-8
537
+ },
538
+ "microsoft/wizardlm-2-8x22b": {
539
+ inputPerToken: 62e-8,
540
+ outputPerToken: 62e-8
541
+ },
542
+ "minimax/minimax-01": {
543
+ inputPerToken: 2e-7,
544
+ outputPerToken: 11e-7
545
+ },
546
+ "minimax/minimax-m1": {
547
+ inputPerToken: 4e-7,
548
+ outputPerToken: 22e-7
549
+ },
550
+ "minimax/minimax-m2": {
551
+ inputPerToken: 255e-9,
552
+ outputPerToken: 1e-6
553
+ },
554
+ "minimax/minimax-m2-her": {
555
+ inputPerToken: 3e-7,
556
+ outputPerToken: 12e-7
557
+ },
558
+ "minimax/minimax-m2.1": {
559
+ inputPerToken: 27e-8,
560
+ outputPerToken: 95e-8
561
+ },
562
+ "minimax/minimax-m2.5": {
563
+ inputPerToken: 295e-9,
564
+ outputPerToken: 12e-7
565
+ },
566
+ "mistral/codestral-2508": {
567
+ inputPerToken: 3e-7,
568
+ outputPerToken: 9e-7
569
+ },
570
+ "mistral/devstral-2512": {
571
+ inputPerToken: 4e-7,
572
+ outputPerToken: 2e-6
573
+ },
574
+ "mistral/devstral-medium": {
575
+ inputPerToken: 4e-7,
576
+ outputPerToken: 2e-6
577
+ },
578
+ "mistral/devstral-small": {
579
+ inputPerToken: 1e-7,
580
+ outputPerToken: 3e-7
581
+ },
582
+ "mistral/ministral-14b-2512": {
583
+ inputPerToken: 2e-7,
584
+ outputPerToken: 2e-7
585
+ },
586
+ "mistral/ministral-3b-2512": {
587
+ inputPerToken: 1e-7,
588
+ outputPerToken: 1e-7
589
+ },
590
+ "mistral/ministral-8b-2512": {
591
+ inputPerToken: 15e-8,
592
+ outputPerToken: 15e-8
593
+ },
594
+ "mistral/mistral-7b-instruct": {
595
+ inputPerToken: 2e-7,
596
+ outputPerToken: 2e-7
597
+ },
598
+ "mistral/mistral-7b-instruct-v0.1": {
599
+ inputPerToken: 11e-8,
600
+ outputPerToken: 19e-8
601
+ },
602
+ "mistral/mistral-7b-instruct-v0.3": {
603
+ inputPerToken: 2e-7,
604
+ outputPerToken: 2e-7
605
+ },
606
+ "mistral/mistral-large": {
607
+ inputPerToken: 2e-6,
608
+ outputPerToken: 6e-6
609
+ },
610
+ "mistral/mistral-large-2407": {
611
+ inputPerToken: 2e-6,
612
+ outputPerToken: 6e-6
613
+ },
614
+ "mistral/mistral-large-2411": {
615
+ inputPerToken: 2e-6,
616
+ outputPerToken: 6e-6
617
+ },
618
+ "mistral/mistral-large-2512": {
619
+ inputPerToken: 5e-7,
620
+ outputPerToken: 15e-7
621
+ },
622
+ "mistral/mistral-medium-3": {
623
+ inputPerToken: 4e-7,
624
+ outputPerToken: 2e-6
625
+ },
626
+ "mistral/mistral-medium-3.1": {
627
+ inputPerToken: 4e-7,
628
+ outputPerToken: 2e-6
629
+ },
630
+ "mistral/mistral-nemo": {
631
+ inputPerToken: 2e-8,
632
+ outputPerToken: 4e-8
633
+ },
634
+ "mistral/mistral-saba": {
635
+ inputPerToken: 2e-7,
636
+ outputPerToken: 6e-7
637
+ },
638
+ "mistral/mistral-small": {
639
+ inputPerToken: 1e-7,
640
+ outputPerToken: 3e-7
641
+ },
642
+ "mistral/mistral-small-24b-instruct-2501": {
643
+ inputPerToken: 5e-8,
644
+ outputPerToken: 8e-8
645
+ },
646
+ "mistral/mistral-small-3.1-24b-instruct": {
647
+ inputPerToken: 35e-8,
648
+ outputPerToken: 56e-8
649
+ },
650
+ "mistral/mistral-small-3.2-24b-instruct": {
651
+ inputPerToken: 6e-8,
652
+ outputPerToken: 18e-8
653
+ },
654
+ "mistral/mistral-small-creative": {
655
+ inputPerToken: 1e-7,
656
+ outputPerToken: 3e-7
657
+ },
658
+ "mistral/mixtral-8x22b-instruct": {
659
+ inputPerToken: 2e-6,
660
+ outputPerToken: 6e-6
661
+ },
662
+ "mistral/mixtral-8x7b-instruct": {
663
+ inputPerToken: 54e-8,
664
+ outputPerToken: 54e-8
665
+ },
666
+ "mistral/pixtral-large-2411": {
667
+ inputPerToken: 2e-6,
668
+ outputPerToken: 6e-6
669
+ },
670
+ "mistral/voxtral-small-24b-2507": {
671
+ inputPerToken: 1e-7,
672
+ outputPerToken: 3e-7
673
+ },
674
+ "moonshotai/kimi-k2": {
675
+ inputPerToken: 55e-8,
676
+ outputPerToken: 22e-7
677
+ },
678
+ "moonshotai/kimi-k2-0905": {
679
+ inputPerToken: 4e-7,
680
+ outputPerToken: 2e-6
681
+ },
682
+ "moonshotai/kimi-k2-0905:exacto": {
683
+ inputPerToken: 6e-7,
684
+ outputPerToken: 25e-7
685
+ },
686
+ "moonshotai/kimi-k2-thinking": {
687
+ inputPerToken: 47e-8,
688
+ outputPerToken: 2e-6
689
+ },
690
+ "moonshotai/kimi-k2.5": {
691
+ inputPerToken: 45e-8,
692
+ outputPerToken: 22e-7
693
+ },
694
+ "morph/morph-v3-fast": {
695
+ inputPerToken: 8e-7,
696
+ outputPerToken: 12e-7
697
+ },
698
+ "morph/morph-v3-large": {
699
+ inputPerToken: 9e-7,
700
+ outputPerToken: 19e-7
701
+ },
702
+ "neversleep/llama-3.1-lumimaid-8b": {
703
+ inputPerToken: 9e-8,
704
+ outputPerToken: 6e-7
705
+ },
706
+ "neversleep/noromaid-20b": {
707
+ inputPerToken: 1e-6,
708
+ outputPerToken: 175e-8
709
+ },
710
+ "nex-agi/deepseek-v3.1-nex-n1": {
711
+ inputPerToken: 27e-8,
712
+ outputPerToken: 1e-6
713
+ },
714
+ "nousresearch/hermes-2-pro-llama-3-8b": {
715
+ inputPerToken: 14e-8,
716
+ outputPerToken: 14e-8
717
+ },
718
+ "nousresearch/hermes-3-llama-3.1-405b": {
719
+ inputPerToken: 1e-6,
720
+ outputPerToken: 1e-6
721
+ },
722
+ "nousresearch/hermes-3-llama-3.1-70b": {
723
+ inputPerToken: 3e-7,
724
+ outputPerToken: 3e-7
725
+ },
726
+ "nousresearch/hermes-4-405b": {
727
+ inputPerToken: 1e-6,
728
+ outputPerToken: 3e-6
729
+ },
730
+ "nousresearch/hermes-4-70b": {
731
+ inputPerToken: 13e-8,
732
+ outputPerToken: 4e-7
733
+ },
734
+ "nvidia/llama-3.1-nemotron-70b-instruct": {
735
+ inputPerToken: 12e-7,
736
+ outputPerToken: 12e-7
737
+ },
738
+ "nvidia/llama-3.3-nemotron-super-49b-v1.5": {
739
+ inputPerToken: 1e-7,
740
+ outputPerToken: 4e-7
741
+ },
742
+ "nvidia/nemotron-3-nano-30b-a3b": {
743
+ inputPerToken: 5e-8,
744
+ outputPerToken: 2e-7
745
+ },
746
+ "nvidia/nemotron-nano-12b-v2-vl": {
747
+ inputPerToken: 2e-7,
748
+ outputPerToken: 6e-7
749
+ },
750
+ "nvidia/nemotron-nano-9b-v2": {
751
+ inputPerToken: 4e-8,
752
+ outputPerToken: 16e-8
753
+ },
754
+ "openai/gpt-3.5-turbo": {
755
+ inputPerToken: 5e-7,
756
+ outputPerToken: 15e-7
757
+ },
758
+ "openai/gpt-3.5-turbo-0613": {
759
+ inputPerToken: 1e-6,
760
+ outputPerToken: 2e-6
761
+ },
762
+ "openai/gpt-3.5-turbo-16k": {
763
+ inputPerToken: 3e-6,
764
+ outputPerToken: 4e-6
765
+ },
766
+ "openai/gpt-3.5-turbo-instruct": {
767
+ inputPerToken: 15e-7,
768
+ outputPerToken: 2e-6
769
+ },
770
+ "openai/gpt-4": {
771
+ inputPerToken: 3e-5,
772
+ outputPerToken: 6e-5
773
+ },
774
+ "openai/gpt-4-0314": {
775
+ inputPerToken: 3e-5,
776
+ outputPerToken: 6e-5
777
+ },
778
+ "openai/gpt-4-1106-preview": {
779
+ inputPerToken: 1e-5,
780
+ outputPerToken: 3e-5
781
+ },
782
+ "openai/gpt-4-turbo": {
783
+ inputPerToken: 1e-5,
784
+ outputPerToken: 3e-5
785
+ },
786
+ "openai/gpt-4-turbo-preview": {
787
+ inputPerToken: 1e-5,
788
+ outputPerToken: 3e-5
789
+ },
790
+ "openai/gpt-4.1": {
791
+ inputPerToken: 2e-6,
792
+ outputPerToken: 8e-6
793
+ },
794
+ "openai/gpt-4.1-mini": {
795
+ inputPerToken: 4e-7,
796
+ outputPerToken: 16e-7
797
+ },
798
+ "openai/gpt-4.1-nano": {
799
+ inputPerToken: 1e-7,
800
+ outputPerToken: 4e-7
801
+ },
802
+ "openai/gpt-4o": {
803
+ inputPerToken: 25e-7,
804
+ outputPerToken: 1e-5
805
+ },
806
+ "openai/gpt-4o-2024-05-13": {
807
+ inputPerToken: 5e-6,
808
+ outputPerToken: 15e-6
809
+ },
810
+ "openai/gpt-4o-2024-08-06": {
811
+ inputPerToken: 25e-7,
812
+ outputPerToken: 1e-5
813
+ },
814
+ "openai/gpt-4o-2024-11-20": {
815
+ inputPerToken: 25e-7,
816
+ outputPerToken: 1e-5
817
+ },
818
+ "openai/gpt-4o-audio-preview": {
819
+ inputPerToken: 25e-7,
820
+ outputPerToken: 1e-5
821
+ },
822
+ "openai/gpt-4o-mini": {
823
+ inputPerToken: 15e-8,
824
+ outputPerToken: 6e-7
825
+ },
826
+ "openai/gpt-4o-mini-2024-07-18": {
827
+ inputPerToken: 15e-8,
828
+ outputPerToken: 6e-7
829
+ },
830
+ "openai/gpt-4o-mini-search-preview": {
831
+ inputPerToken: 15e-8,
832
+ outputPerToken: 6e-7
833
+ },
834
+ "openai/gpt-4o-search-preview": {
835
+ inputPerToken: 25e-7,
836
+ outputPerToken: 1e-5
837
+ },
838
+ "openai/gpt-4o:extended": {
839
+ inputPerToken: 6e-6,
840
+ outputPerToken: 18e-6
841
+ },
842
+ "openai/gpt-5": {
843
+ inputPerToken: 125e-8,
844
+ outputPerToken: 1e-5
845
+ },
846
+ "openai/gpt-5-chat": {
847
+ inputPerToken: 125e-8,
848
+ outputPerToken: 1e-5
849
+ },
850
+ "openai/gpt-5-codex": {
851
+ inputPerToken: 125e-8,
852
+ outputPerToken: 1e-5
853
+ },
854
+ "openai/gpt-5-image": {
855
+ inputPerToken: 1e-5,
856
+ outputPerToken: 1e-5
857
+ },
858
+ "openai/gpt-5-image-mini": {
859
+ inputPerToken: 25e-7,
860
+ outputPerToken: 2e-6
861
+ },
862
+ "openai/gpt-5-mini": {
863
+ inputPerToken: 25e-8,
864
+ outputPerToken: 2e-6
865
+ },
866
+ "openai/gpt-5-nano": {
867
+ inputPerToken: 5e-8,
868
+ outputPerToken: 4e-7
869
+ },
870
+ "openai/gpt-5-pro": {
871
+ inputPerToken: 15e-6,
872
+ outputPerToken: 12e-5
873
+ },
874
+ "openai/gpt-5.1": {
875
+ inputPerToken: 125e-8,
876
+ outputPerToken: 1e-5
877
+ },
878
+ "openai/gpt-5.1-chat": {
879
+ inputPerToken: 125e-8,
880
+ outputPerToken: 1e-5
881
+ },
882
+ "openai/gpt-5.1-codex": {
883
+ inputPerToken: 125e-8,
884
+ outputPerToken: 1e-5
885
+ },
886
+ "openai/gpt-5.1-codex-max": {
887
+ inputPerToken: 125e-8,
888
+ outputPerToken: 1e-5
889
+ },
890
+ "openai/gpt-5.1-codex-mini": {
891
+ inputPerToken: 25e-8,
892
+ outputPerToken: 2e-6
893
+ },
894
+ "openai/gpt-5.2": {
895
+ inputPerToken: 175e-8,
896
+ outputPerToken: 14e-6
897
+ },
898
+ "openai/gpt-5.2-chat": {
899
+ inputPerToken: 175e-8,
900
+ outputPerToken: 14e-6
901
+ },
902
+ "openai/gpt-5.2-codex": {
903
+ inputPerToken: 175e-8,
904
+ outputPerToken: 14e-6
905
+ },
906
+ "openai/gpt-5.2-pro": {
907
+ inputPerToken: 21e-6,
908
+ outputPerToken: 168e-6
909
+ },
910
+ "openai/gpt-5.3-codex": {
911
+ inputPerToken: 175e-8,
912
+ outputPerToken: 14e-6
913
+ },
914
+ "openai/gpt-audio": {
915
+ inputPerToken: 25e-7,
916
+ outputPerToken: 1e-5
917
+ },
918
+ "openai/gpt-audio-mini": {
919
+ inputPerToken: 6e-7,
920
+ outputPerToken: 24e-7
921
+ },
922
+ "openai/gpt-oss-120b": {
923
+ inputPerToken: 39e-9,
924
+ outputPerToken: 19e-8
925
+ },
926
+ "openai/gpt-oss-120b:exacto": {
927
+ inputPerToken: 39e-9,
928
+ outputPerToken: 19e-8
929
+ },
930
+ "openai/gpt-oss-20b": {
931
+ inputPerToken: 3e-8,
932
+ outputPerToken: 14e-8
933
+ },
934
+ "openai/gpt-oss-safeguard-20b": {
935
+ inputPerToken: 75e-9,
936
+ outputPerToken: 3e-7
937
+ },
938
+ "openai/o1": {
939
+ inputPerToken: 15e-6,
940
+ outputPerToken: 6e-5
941
+ },
942
+ "openai/o1-pro": {
943
+ inputPerToken: 15e-5,
944
+ outputPerToken: 6e-4
945
+ },
946
+ "openai/o3": {
947
+ inputPerToken: 2e-6,
948
+ outputPerToken: 8e-6
949
+ },
950
+ "openai/o3-deep-research": {
951
+ inputPerToken: 1e-5,
952
+ outputPerToken: 4e-5
953
+ },
954
+ "openai/o3-mini": {
955
+ inputPerToken: 11e-7,
956
+ outputPerToken: 44e-7
957
+ },
958
+ "openai/o3-mini-high": {
959
+ inputPerToken: 11e-7,
960
+ outputPerToken: 44e-7
961
+ },
962
+ "openai/o3-pro": {
963
+ inputPerToken: 2e-5,
964
+ outputPerToken: 8e-5
965
+ },
966
+ "openai/o4-mini": {
967
+ inputPerToken: 11e-7,
968
+ outputPerToken: 44e-7
969
+ },
970
+ "openai/o4-mini-deep-research": {
971
+ inputPerToken: 2e-6,
972
+ outputPerToken: 8e-6
973
+ },
974
+ "openai/o4-mini-high": {
975
+ inputPerToken: 11e-7,
976
+ outputPerToken: 44e-7
977
+ },
978
+ "opengvlab/internvl3-78b": {
979
+ inputPerToken: 15e-8,
980
+ outputPerToken: 6e-7
981
+ },
982
+ "perplexity/sonar": {
983
+ inputPerToken: 1e-6,
984
+ outputPerToken: 1e-6
985
+ },
986
+ "perplexity/sonar-deep-research": {
987
+ inputPerToken: 2e-6,
988
+ outputPerToken: 8e-6
989
+ },
990
+ "perplexity/sonar-pro": {
991
+ inputPerToken: 3e-6,
992
+ outputPerToken: 15e-6
993
+ },
994
+ "perplexity/sonar-pro-search": {
995
+ inputPerToken: 3e-6,
996
+ outputPerToken: 15e-6
997
+ },
998
+ "perplexity/sonar-reasoning-pro": {
999
+ inputPerToken: 2e-6,
1000
+ outputPerToken: 8e-6
1001
+ },
1002
+ "prime-intellect/intellect-3": {
1003
+ inputPerToken: 2e-7,
1004
+ outputPerToken: 11e-7
1005
+ },
1006
+ "qwen/qwen-2.5-72b-instruct": {
1007
+ inputPerToken: 12e-8,
1008
+ outputPerToken: 39e-8
1009
+ },
1010
+ "qwen/qwen-2.5-7b-instruct": {
1011
+ inputPerToken: 4e-8,
1012
+ outputPerToken: 1e-7
1013
+ },
1014
+ "qwen/qwen-2.5-coder-32b-instruct": {
1015
+ inputPerToken: 20000000000000002e-23,
1016
+ outputPerToken: 20000000000000002e-23
1017
+ },
1018
+ "qwen/qwen-2.5-vl-7b-instruct": {
1019
+ inputPerToken: 20000000000000002e-23,
1020
+ outputPerToken: 20000000000000002e-23
1021
+ },
1022
+ "qwen/qwen-max": {
1023
+ inputPerToken: 16e-7,
1024
+ outputPerToken: 64e-7
1025
+ },
1026
+ "qwen/qwen-plus": {
1027
+ inputPerToken: 4e-7,
1028
+ outputPerToken: 12e-7
1029
+ },
1030
+ "qwen/qwen-plus-2025-07-28": {
1031
+ inputPerToken: 4e-7,
1032
+ outputPerToken: 12e-7
1033
+ },
1034
+ "qwen/qwen-plus-2025-07-28:thinking": {
1035
+ inputPerToken: 4e-7,
1036
+ outputPerToken: 12e-7
1037
+ },
1038
+ "qwen/qwen-turbo": {
1039
+ inputPerToken: 5e-8,
1040
+ outputPerToken: 2e-7
1041
+ },
1042
+ "qwen/qwen-vl-max": {
1043
+ inputPerToken: 8e-7,
1044
+ outputPerToken: 32e-7
1045
+ },
1046
+ "qwen/qwen-vl-plus": {
1047
+ inputPerToken: 21e-8,
1048
+ outputPerToken: 63e-8
1049
+ },
1050
+ "qwen/qwen2.5-coder-7b-instruct": {
1051
+ inputPerToken: 3e-8,
1052
+ outputPerToken: 9e-8
1053
+ },
1054
+ "qwen/qwen2.5-vl-32b-instruct": {
1055
+ inputPerToken: 2e-7,
1056
+ outputPerToken: 6e-7
1057
+ },
1058
+ "qwen/qwen2.5-vl-72b-instruct": {
1059
+ inputPerToken: 8e-7,
1060
+ outputPerToken: 8e-7
1061
+ },
1062
+ "qwen/qwen3-14b": {
1063
+ inputPerToken: 6e-8,
1064
+ outputPerToken: 24e-8
1065
+ },
1066
+ "qwen/qwen3-235b-a22b": {
1067
+ inputPerToken: 455e-9,
1068
+ outputPerToken: 182e-8
1069
+ },
1070
+ "qwen/qwen3-235b-a22b-2507": {
1071
+ inputPerToken: 71e-9,
1072
+ outputPerToken: 1e-7
1073
+ },
1074
+ "qwen/qwen3-30b-a3b": {
1075
+ inputPerToken: 8e-8,
1076
+ outputPerToken: 28e-8
1077
+ },
1078
+ "qwen/qwen3-30b-a3b-instruct-2507": {
1079
+ inputPerToken: 9e-8,
1080
+ outputPerToken: 3e-7
1081
+ },
1082
+ "qwen/qwen3-30b-a3b-thinking-2507": {
1083
+ inputPerToken: 51e-9,
1084
+ outputPerToken: 34e-8
1085
+ },
1086
+ "qwen/qwen3-32b": {
1087
+ inputPerToken: 8e-8,
1088
+ outputPerToken: 24e-8
1089
+ },
1090
+ "qwen/qwen3-8b": {
1091
+ inputPerToken: 5e-8,
1092
+ outputPerToken: 4e-7
1093
+ },
1094
+ "qwen/qwen3-coder": {
1095
+ inputPerToken: 22e-8,
1096
+ outputPerToken: 1e-6
1097
+ },
1098
+ "qwen/qwen3-coder-30b-a3b-instruct": {
1099
+ inputPerToken: 7e-8,
1100
+ outputPerToken: 27e-8
1101
+ },
1102
+ "qwen/qwen3-coder-flash": {
1103
+ inputPerToken: 3e-7,
1104
+ outputPerToken: 15e-7
1105
+ },
1106
+ "qwen/qwen3-coder-next": {
1107
+ inputPerToken: 12e-8,
1108
+ outputPerToken: 75e-8
1109
+ },
1110
+ "qwen/qwen3-coder-plus": {
1111
+ inputPerToken: 1e-6,
1112
+ outputPerToken: 5e-6
1113
+ },
1114
+ "qwen/qwen3-coder:exacto": {
1115
+ inputPerToken: 22e-8,
1116
+ outputPerToken: 18e-7
1117
+ },
1118
+ "qwen/qwen3-max": {
1119
+ inputPerToken: 12e-7,
1120
+ outputPerToken: 6e-6
1121
+ },
1122
+ "qwen/qwen3-max-thinking": {
1123
+ inputPerToken: 12e-7,
1124
+ outputPerToken: 6e-6
1125
+ },
1126
+ "qwen/qwen3-next-80b-a3b-instruct": {
1127
+ inputPerToken: 9e-8,
1128
+ outputPerToken: 11e-7
1129
+ },
1130
+ "qwen/qwen3-next-80b-a3b-thinking": {
1131
+ inputPerToken: 15e-8,
1132
+ outputPerToken: 12e-7
1133
+ },
1134
+ "qwen/qwen3-vl-235b-a22b-instruct": {
1135
+ inputPerToken: 2e-7,
1136
+ outputPerToken: 88e-8
1137
+ },
1138
+ "qwen/qwen3-vl-30b-a3b-instruct": {
1139
+ inputPerToken: 13e-8,
1140
+ outputPerToken: 52e-8
1141
+ },
1142
+ "qwen/qwen3-vl-32b-instruct": {
1143
+ inputPerToken: 104e-9,
1144
+ outputPerToken: 416e-9
1145
+ },
1146
+ "qwen/qwen3-vl-8b-instruct": {
1147
+ inputPerToken: 8e-8,
1148
+ outputPerToken: 5e-7
1149
+ },
1150
+ "qwen/qwen3-vl-8b-thinking": {
1151
+ inputPerToken: 117e-9,
1152
+ outputPerToken: 1365e-9
1153
+ },
1154
+ "qwen/qwen3.5-122b-a10b": {
1155
+ inputPerToken: 4e-7,
1156
+ outputPerToken: 32e-7
1157
+ },
1158
+ "qwen/qwen3.5-27b": {
1159
+ inputPerToken: 3e-7,
1160
+ outputPerToken: 24e-7
1161
+ },
1162
+ "qwen/qwen3.5-35b-a3b": {
1163
+ inputPerToken: 25e-8,
1164
+ outputPerToken: 2e-6
1165
+ },
1166
+ "qwen/qwen3.5-397b-a17b": {
1167
+ inputPerToken: 55e-8,
1168
+ outputPerToken: 35e-7
1169
+ },
1170
+ "qwen/qwen3.5-flash-02-23": {
1171
+ inputPerToken: 1e-7,
1172
+ outputPerToken: 4e-7
1173
+ },
1174
+ "qwen/qwen3.5-plus-02-15": {
1175
+ inputPerToken: 4e-7,
1176
+ outputPerToken: 24e-7
1177
+ },
1178
+ "qwen/qwq-32b": {
1179
+ inputPerToken: 15e-8,
1180
+ outputPerToken: 4e-7
1181
+ },
1182
+ "raifle/sorcererlm-8x22b": {
1183
+ inputPerToken: 45e-7,
1184
+ outputPerToken: 45e-7
1185
+ },
1186
+ "relace/relace-apply-3": {
1187
+ inputPerToken: 85e-8,
1188
+ outputPerToken: 125e-8
1189
+ },
1190
+ "relace/relace-search": {
1191
+ inputPerToken: 1e-6,
1192
+ outputPerToken: 3e-6
1193
+ },
1194
+ "sao10k/l3-euryale-70b": {
1195
+ inputPerToken: 148e-8,
1196
+ outputPerToken: 148e-8
1197
+ },
1198
+ "sao10k/l3-lunaris-8b": {
1199
+ inputPerToken: 4e-8,
1200
+ outputPerToken: 5e-8
1201
+ },
1202
+ "sao10k/l3.1-70b-hanami-x1": {
1203
+ inputPerToken: 3e-6,
1204
+ outputPerToken: 3e-6
1205
+ },
1206
+ "sao10k/l3.1-euryale-70b": {
1207
+ inputPerToken: 65e-8,
1208
+ outputPerToken: 75e-8
1209
+ },
1210
+ "sao10k/l3.3-euryale-70b": {
1211
+ inputPerToken: 65e-8,
1212
+ outputPerToken: 75e-8
1213
+ },
1214
+ "stepfun/step-3.5-flash": {
1215
+ inputPerToken: 1e-7,
1216
+ outputPerToken: 3e-7
1217
+ },
1218
+ "switchpoint/router": {
1219
+ inputPerToken: 85e-8,
1220
+ outputPerToken: 34e-7
1221
+ },
1222
+ "tencent/hunyuan-a13b-instruct": {
1223
+ inputPerToken: 14e-8,
1224
+ outputPerToken: 57e-8
1225
+ },
1226
+ "thedrummer/cydonia-24b-v4.1": {
1227
+ inputPerToken: 3e-7,
1228
+ outputPerToken: 5e-7
1229
+ },
1230
+ "thedrummer/rocinante-12b": {
1231
+ inputPerToken: 17e-8,
1232
+ outputPerToken: 43e-8
1233
+ },
1234
+ "thedrummer/skyfall-36b-v2": {
1235
+ inputPerToken: 55e-8,
1236
+ outputPerToken: 8e-7
1237
+ },
1238
+ "thedrummer/unslopnemo-12b": {
1239
+ inputPerToken: 4e-7,
1240
+ outputPerToken: 4e-7
1241
+ },
1242
+ "tngtech/deepseek-r1t2-chimera": {
1243
+ inputPerToken: 25e-8,
1244
+ outputPerToken: 85e-8
1245
+ },
1246
+ "undi95/remm-slerp-l2-13b": {
1247
+ inputPerToken: 45e-8,
1248
+ outputPerToken: 65e-8
1249
+ },
1250
+ "writer/palmyra-x5": {
1251
+ inputPerToken: 6e-7,
1252
+ outputPerToken: 6e-6
1253
+ },
1254
+ "xai/grok-3": {
1255
+ inputPerToken: 3e-6,
1256
+ outputPerToken: 15e-6
1257
+ },
1258
+ "xai/grok-3-beta": {
1259
+ inputPerToken: 3e-6,
1260
+ outputPerToken: 15e-6
1261
+ },
1262
+ "xai/grok-3-mini": {
1263
+ inputPerToken: 3e-7,
1264
+ outputPerToken: 5e-7
1265
+ },
1266
+ "xai/grok-3-mini-beta": {
1267
+ inputPerToken: 3e-7,
1268
+ outputPerToken: 5e-7
1269
+ },
1270
+ "xai/grok-4": {
1271
+ inputPerToken: 3e-6,
1272
+ outputPerToken: 15e-6
1273
+ },
1274
+ "xai/grok-4-fast": {
1275
+ inputPerToken: 2e-7,
1276
+ outputPerToken: 5e-7
1277
+ },
1278
+ "xai/grok-4.1-fast": {
1279
+ inputPerToken: 2e-7,
1280
+ outputPerToken: 5e-7
1281
+ },
1282
+ "xai/grok-code-fast-1": {
1283
+ inputPerToken: 2e-7,
1284
+ outputPerToken: 15e-7
1285
+ },
1286
+ "xiaomi/mimo-v2-flash": {
1287
+ inputPerToken: 9e-8,
1288
+ outputPerToken: 29e-8
1289
+ },
1290
+ "z-ai/glm-4-32b": {
1291
+ inputPerToken: 1e-7,
1292
+ outputPerToken: 1e-7
1293
+ },
1294
+ "z-ai/glm-4.5": {
1295
+ inputPerToken: 55e-8,
1296
+ outputPerToken: 2e-6
1297
+ },
1298
+ "z-ai/glm-4.5-air": {
1299
+ inputPerToken: 13e-8,
1300
+ outputPerToken: 85e-8
1301
+ },
1302
+ "z-ai/glm-4.5v": {
1303
+ inputPerToken: 6e-7,
1304
+ outputPerToken: 18e-7
1305
+ },
1306
+ "z-ai/glm-4.6": {
1307
+ inputPerToken: 35e-8,
1308
+ outputPerToken: 171e-8
1309
+ },
1310
+ "z-ai/glm-4.6:exacto": {
1311
+ inputPerToken: 44e-8,
1312
+ outputPerToken: 176e-8
1313
+ },
1314
+ "z-ai/glm-4.6v": {
1315
+ inputPerToken: 3e-7,
1316
+ outputPerToken: 9e-7
1317
+ },
1318
+ "z-ai/glm-4.7": {
1319
+ inputPerToken: 3e-7,
1320
+ outputPerToken: 14e-7
1321
+ },
1322
+ "z-ai/glm-4.7-flash": {
1323
+ inputPerToken: 6e-8,
1324
+ outputPerToken: 4e-7
1325
+ },
1326
+ "z-ai/glm-5": {
1327
+ inputPerToken: 95e-8,
1328
+ outputPerToken: 255e-8
1329
+ }
1330
+ }
1331
+ };
1332
+
1333
+ // src/pricing/lookup.ts
1334
+ var models = catalog_default.models;
1335
+ var modelNameIndex = /* @__PURE__ */ new Map();
1336
+ for (const key of Object.keys(models)) {
1337
+ const name = key.split("/").slice(1).join("/");
1338
+ if (name && !modelNameIndex.has(name)) {
1339
+ modelNameIndex.set(name, key);
1340
+ }
1341
+ }
1342
+ function lookupPricing(providerId) {
1343
+ if (models[providerId]) return models[providerId];
1344
+ const model = providerId.split("/").slice(1).join("/");
1345
+ if (!model) return void 0;
1346
+ const asOpenai = `openai/${model}`;
1347
+ if (models[asOpenai]) return models[asOpenai];
1348
+ const crossKey = modelNameIndex.get(model);
1349
+ if (crossKey) return models[crossKey];
1350
+ return void 0;
1351
+ }
1352
+ function registerPricing(providerId, pricing) {
1353
+ models[providerId] = pricing;
1354
+ }
1355
+ function estimateCost(pricing, promptTokens, completionTokens) {
1356
+ return pricing.inputPerToken * promptTokens + pricing.outputPerToken * completionTokens;
1357
+ }
1358
+
1359
+ // src/scorers/cost.ts
1360
+ var costScorer = ({ result }, providerId) => {
1361
+ const promptTokens = result.usage?.promptTokens ?? 0;
1362
+ const completionTokens = result.usage?.completionTokens ?? 0;
1363
+ const totalTokens = promptTokens + completionTokens;
1364
+ const pricing = lookupPricing(providerId);
1365
+ if (!pricing) {
1366
+ return {
1367
+ name: "cost",
1368
+ value: -1,
1369
+ details: {
1370
+ estimatedUsd: null,
1371
+ promptTokens,
1372
+ completionTokens,
1373
+ totalTokens,
1374
+ note: "No pricing data available for this model"
1375
+ }
1376
+ };
1377
+ }
1378
+ const usd = estimateCost(pricing, promptTokens, completionTokens);
1379
+ return {
1380
+ name: "cost",
1381
+ value: usd,
1382
+ details: {
1383
+ estimatedUsd: usd,
1384
+ promptTokens,
1385
+ completionTokens,
1386
+ totalTokens
1387
+ }
1388
+ };
1389
+ };
1390
+
1391
+ // src/scorers/correctness.ts
1392
+ var correctnessScorer = ({ task, result }) => {
1393
+ if (task.expected === void 0) {
1394
+ return { name: "correctness", value: 0.5, details: { reason: "no expected value" } };
1395
+ }
1396
+ const match = deepEqual(task.expected, result.output);
1397
+ return {
1398
+ name: "correctness",
1399
+ value: match ? 1 : 0,
1400
+ details: { expected: task.expected, actual: result.output }
1401
+ };
1402
+ };
1403
+ function deepEqual(a, b) {
1404
+ if (a === b) return true;
1405
+ if (typeof a === "string" && typeof b === "string") {
1406
+ return a.trim().toLowerCase() === b.trim().toLowerCase();
1407
+ }
1408
+ if (typeof a !== typeof b) return false;
1409
+ if (a === null || b === null) return a === b;
1410
+ if (Array.isArray(a) && Array.isArray(b)) {
1411
+ if (a.length !== b.length) return false;
1412
+ return a.every((val, i) => deepEqual(val, b[i]));
1413
+ }
1414
+ if (typeof a === "object" && typeof b === "object") {
1415
+ const objA = a;
1416
+ const objB = b;
1417
+ const keysA = Object.keys(objA);
1418
+ const keysB = Object.keys(objB);
1419
+ if (keysA.length !== keysB.length) return false;
1420
+ return keysA.every((key) => key in objB && deepEqual(objA[key], objB[key]));
1421
+ }
1422
+ return a === b;
1423
+ }
1424
+
1425
+ // src/scorers/schema-correctness.ts
1426
+ var schemaCorrectnessScorer = ({ task, result }) => {
1427
+ if (!task.schema) {
1428
+ return { name: "schema-correctness", value: -1, details: { reason: "no schema defined" } };
1429
+ }
1430
+ let data = result.output;
1431
+ if (typeof data === "string") {
1432
+ try {
1433
+ data = JSON.parse(data);
1434
+ } catch {
1435
+ return {
1436
+ name: "schema-correctness",
1437
+ value: 0,
1438
+ details: { reason: "output is not valid JSON" }
1439
+ };
1440
+ }
1441
+ }
1442
+ const parsed = task.schema.safeParse(data);
1443
+ return {
1444
+ name: "schema-correctness",
1445
+ value: parsed.success ? 1 : 0,
1446
+ details: parsed.success ? { valid: true } : { valid: false, errors: parsed.error.issues.map((i) => i.message) }
1447
+ };
1448
+ };
1449
+
1450
+ // src/scorers/fuzzy-similarity.ts
1451
+ var fuzzySimilarityScorer = ({ task, result }) => {
1452
+ if (task.expected === void 0) {
1453
+ return { name: "fuzzy-similarity", value: -1, details: { reason: "no expected value" } };
1454
+ }
1455
+ const a = stringify(task.expected);
1456
+ const b = stringify(result.output);
1457
+ const similarity = jaccardSimilarity(tokenize(a), tokenize(b));
1458
+ return {
1459
+ name: "fuzzy-similarity",
1460
+ value: Math.round(similarity * 100) / 100,
1461
+ details: { method: "jaccard", expectedTokens: tokenize(a).size, actualTokens: tokenize(b).size }
1462
+ };
1463
+ };
1464
+ function stringify(value) {
1465
+ if (typeof value === "string") return value.toLowerCase();
1466
+ return JSON.stringify(value).toLowerCase();
1467
+ }
1468
+ function tokenize(text) {
1469
+ return new Set(text.match(/\w+/g) ?? []);
1470
+ }
1471
+ function jaccardSimilarity(a, b) {
1472
+ if (a.size === 0 && b.size === 0) return 1;
1473
+ let intersection = 0;
1474
+ for (const token of a) {
1475
+ if (b.has(token)) intersection++;
1476
+ }
1477
+ const union = a.size + b.size - intersection;
1478
+ return union === 0 ? 1 : intersection / union;
1479
+ }
1480
+
1481
+ // src/scorers/llm-judge.ts
1482
+ var import_openai = __toESM(require("openai"), 1);
1483
+ var JUDGE_PROMPT = `You are a strict scoring judge. Evaluate the actual output against the expected output on three criteria. Score each from 0.0 to 1.0 using the full range (not just 0, 0.5, 1).
1484
+
1485
+ Criteria:
1486
+ 1. Accuracy \u2014 are the facts, entities, and claims correct? Penalize hallucinations or wrong details.
1487
+ 2. Completeness \u2014 does it capture all key information from the expected output? Penalize missing points.
1488
+ 3. Conciseness \u2014 is it free of unnecessary filler, repetition, or tangential content? Penalize verbosity.
1489
+
1490
+ Respond with ONLY this exact format \u2014 three lines, no other text:
1491
+ accuracy: <number>
1492
+ completeness: <number>
1493
+ conciseness: <number>
1494
+
1495
+ Task: {task}
1496
+ Expected: {expected}
1497
+ Actual: {actual}`;
1498
+ function resolveJudgeClient(configModel) {
1499
+ const model = configModel ?? process.env.DUELIST_JUDGE_MODEL ?? "gpt-4o-mini";
1500
+ if (model.startsWith("gemini") && process.env.GOOGLE_API_KEY) {
1501
+ return {
1502
+ client: new import_openai.default({
1503
+ apiKey: process.env.GOOGLE_API_KEY,
1504
+ baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/"
1505
+ }),
1506
+ model
1507
+ };
1508
+ }
1509
+ if (!process.env.OPENAI_API_KEY && process.env.AZURE_OPENAI_API_KEY) {
1510
+ return {
1511
+ client: new import_openai.AzureOpenAI({
1512
+ apiKey: process.env.AZURE_OPENAI_API_KEY,
1513
+ endpoint: process.env.AZURE_OPENAI_ENDPOINT,
1514
+ apiVersion: process.env.AZURE_OPENAI_API_VERSION ?? "2024-12-01-preview",
1515
+ deployment: model
1516
+ }),
1517
+ model
1518
+ };
1519
+ }
1520
+ const apiKey = process.env.OPENAI_API_KEY;
1521
+ if (!apiKey) return void 0;
1522
+ return { client: new import_openai.default({ apiKey }), model };
1523
+ }
1524
+ function createLlmJudgeScorer(judgeModel) {
1525
+ let cached = void 0;
1526
+ return async ({ task, result }) => {
1527
+ if (task.expected === void 0) {
1528
+ return { name: "llm-judge-correctness", value: -1, details: { reason: "no expected value" } };
1529
+ }
1530
+ if (cached === void 0) {
1531
+ cached = resolveJudgeClient(judgeModel) ?? null;
1532
+ }
1533
+ if (!cached) {
1534
+ return {
1535
+ name: "llm-judge-correctness",
1536
+ value: -1,
1537
+ details: { reason: "no API key available for judge model" }
1538
+ };
1539
+ }
1540
+ const { client, model } = cached;
1541
+ const prompt = JUDGE_PROMPT.replace("{task}", task.prompt).replace("{expected}", JSON.stringify(task.expected)).replace("{actual}", JSON.stringify(result.output));
1542
+ try {
1543
+ const response = await client.chat.completions.create({
1544
+ model,
1545
+ messages: [{ role: "user", content: prompt }],
1546
+ temperature: 0,
1547
+ max_tokens: 2048
1548
+ });
1549
+ const content = response.choices[0]?.message?.content?.trim() ?? "";
1550
+ const parsed = {};
1551
+ for (const line of content.split("\n")) {
1552
+ const match = line.match(/^(accuracy|completeness|conciseness)\s*:\s*([\d.]+)/i);
1553
+ if (match) parsed[match[1].toLowerCase()] = parseFloat(match[2]);
1554
+ }
1555
+ const accuracy = parsed.accuracy;
1556
+ const completeness = parsed.completeness;
1557
+ const conciseness = parsed.conciseness;
1558
+ if (accuracy == null || completeness == null || conciseness == null || [accuracy, completeness, conciseness].some((s) => isNaN(s) || s < 0 || s > 1)) {
1559
+ return {
1560
+ name: "llm-judge-correctness",
1561
+ value: -1,
1562
+ details: { reason: `judge returned unparseable scores: "${content}"`, model }
1563
+ };
1564
+ }
1565
+ const composite = Math.round((accuracy + completeness + conciseness) / 3 * 100) / 100;
1566
+ return {
1567
+ name: "llm-judge-correctness",
1568
+ value: composite,
1569
+ details: { model, accuracy, completeness, conciseness }
1570
+ };
1571
+ } catch (err) {
1572
+ return {
1573
+ name: "llm-judge-correctness",
1574
+ value: -1,
1575
+ details: { reason: `judge call failed: ${err instanceof Error ? err.message : String(err)}` }
1576
+ };
1577
+ }
1578
+ };
1579
+ }
1580
+
1581
+ // src/scorers/tool-usage.ts
1582
+ var toolUsageScorer = ({ task, result }) => {
1583
+ const expectedToolName = task.tools?.[0]?.name;
1584
+ if (!expectedToolName) {
1585
+ return { name: "tool-usage", value: -1, details: { reason: "no tools configured on task" } };
1586
+ }
1587
+ const usedTool = result.toolCalls?.some((c) => c.name === expectedToolName) ?? false;
1588
+ return {
1589
+ name: "tool-usage",
1590
+ value: usedTool ? 1 : 0,
1591
+ details: { expectedToolName, usedTool, toolCalls: result.toolCalls ?? [] }
1592
+ };
1593
+ };
1594
+
1595
+ // src/scorers/index.ts
1596
+ var staticScorers = {
1597
+ latency: latencyScorer,
1598
+ cost: costScorer,
1599
+ correctness: correctnessScorer,
1600
+ "schema-correctness": schemaCorrectnessScorer,
1601
+ "fuzzy-similarity": fuzzySimilarityScorer,
1602
+ "tool-usage": toolUsageScorer
1603
+ };
1604
+ function resolveScorers(names, judgeModel) {
1605
+ return names.map((name) => {
1606
+ if (name === "llm-judge-correctness") {
1607
+ return createLlmJudgeScorer(judgeModel);
1608
+ }
1609
+ const scorer = staticScorers[name];
1610
+ if (!scorer) {
1611
+ throw new Error(`Unknown scorer: "${name}"`);
1612
+ }
1613
+ return scorer;
1614
+ });
1615
+ }
1616
+
1617
+ // src/runner.ts
1618
+ async function runBenchmarks(options) {
1619
+ const { providers, tasks, scorers, runs, onResult } = options;
1620
+ const results = [];
1621
+ for (const task of tasks) {
1622
+ for (const provider of providers) {
1623
+ for (let run = 1; run <= runs; run++) {
1624
+ let result;
1625
+ try {
1626
+ const taskResult = await provider.run({
1627
+ prompt: task.prompt,
1628
+ schema: task.schema,
1629
+ tools: task.tools
1630
+ });
1631
+ const scores = await Promise.all(
1632
+ scorers.map((scorer) => scorer({ task, result: taskResult }, provider.id))
1633
+ );
1634
+ result = {
1635
+ providerId: provider.id,
1636
+ taskName: task.name,
1637
+ run,
1638
+ scores,
1639
+ raw: {
1640
+ output: taskResult.output,
1641
+ latencyMs: taskResult.latencyMs,
1642
+ usage: taskResult.usage,
1643
+ toolCalls: taskResult.toolCalls
1644
+ }
1645
+ };
1646
+ } catch (err) {
1647
+ const message = err instanceof Error ? err.message : String(err);
1648
+ result = {
1649
+ providerId: provider.id,
1650
+ taskName: task.name,
1651
+ run,
1652
+ scores: [],
1653
+ error: message,
1654
+ raw: { output: "", latencyMs: 0 }
1655
+ };
1656
+ }
1657
+ results.push(result);
1658
+ onResult?.(result);
1659
+ }
1660
+ }
1661
+ }
1662
+ return results;
1663
+ }
1664
+
1665
+ // src/reporter/console.ts
1666
+ var reset = "\x1B[0m";
1667
+ var boldCode = "\x1B[1m";
1668
+ var dimCode = "\x1B[2m";
1669
+ var green = "\x1B[32m";
1670
+ var red = "\x1B[31m";
1671
+ var yellow = "\x1B[33m";
1672
+ var cyan = "\x1B[36m";
1673
+ function bold(s) {
1674
+ return `${boldCode}${s}${reset}`;
1675
+ }
1676
+ function dim(s) {
1677
+ return `${dimCode}${s}${reset}`;
1678
+ }
1679
+ function colorScore(value) {
1680
+ const pct = Math.round(value * 100);
1681
+ const str = `${pct}%`;
1682
+ if (value >= 0.8) return `${green}${str}${reset}`;
1683
+ if (value >= 0.5) return `${yellow}${str}${reset}`;
1684
+ return `${red}${str}${reset}`;
1685
+ }
1686
+ function consoleReporter(results) {
1687
+ if (results.length === 0) {
1688
+ console.log("\nNo results to display.\n");
1689
+ return;
1690
+ }
1691
+ const tasks = [...new Set(results.map((r) => r.taskName))];
1692
+ const providers = [...new Set(results.map((r) => r.providerId))];
1693
+ const scorerNames = [...new Set(results.flatMap((r) => r.scores.map((s) => s.name)))];
1694
+ const hasCost = scorerNames.includes("cost");
1695
+ const hasErrors = results.some((r) => r.error);
1696
+ const runsPerCell = Math.max(...results.map((r) => r.run));
1697
+ const runLabel = runsPerCell > 1 ? ` (${runsPerCell} runs each)` : "";
1698
+ console.log("");
1699
+ console.log(` ${bold(`\u2B21 Agent Duelist Results${runLabel}`)}`);
1700
+ console.log(` ${dim("\u2500".repeat(70))}`);
1701
+ console.log("");
1702
+ for (const task of tasks) {
1703
+ console.log(` ${bold(`Task: ${task}`)}`);
1704
+ const cols = [{ label: "Provider", width: 22, align: "left" }];
1705
+ for (const name of scorerNames) {
1706
+ if (name === "latency") cols.push({ label: "Latency", width: 10, align: "right" });
1707
+ else if (name === "cost") {
1708
+ cols.push({ label: "Cost", width: 12, align: "right" });
1709
+ cols.push({ label: "Tokens", width: 9, align: "right" });
1710
+ } else if (name === "correctness") cols.push({ label: "Match", width: 8, align: "right" });
1711
+ else if (name === "schema-correctness") cols.push({ label: "Schema", width: 8, align: "right" });
1712
+ else if (name === "fuzzy-similarity") cols.push({ label: "Fuzzy", width: 8, align: "right" });
1713
+ else if (name === "llm-judge-correctness") cols.push({ label: "Judge", width: 8, align: "right" });
1714
+ else if (name === "tool-usage") cols.push({ label: "Tool", width: 8, align: "right" });
1715
+ else cols.push({ label: name, width: 10, align: "right" });
1716
+ }
1717
+ if (hasErrors) cols.push({ label: "Status", width: 8, align: "left" });
1718
+ const totalWidth = cols.reduce((sum, c) => sum + c.width + 2, 0);
1719
+ console.log(` ${dim(cols.map((c) => pad(c.label, c.width + 2, c.align)).join(""))}`);
1720
+ console.log(` ${dim("\u2500".repeat(totalWidth))}`);
1721
+ for (const provider of providers) {
1722
+ const taskResults = results.filter(
1723
+ (r) => r.taskName === task && r.providerId === provider
1724
+ );
1725
+ const errorResults2 = taskResults.filter((r) => r.error);
1726
+ const successResults = taskResults.filter((r) => !r.error);
1727
+ if (successResults.length === 0 && errorResults2.length > 0) {
1728
+ const cells2 = [pad(provider, 24, "left")];
1729
+ for (const name of scorerNames) {
1730
+ if (name === "cost") {
1731
+ cells2.push(pad("\u2014", 14, "right"));
1732
+ cells2.push(pad("\u2014", 11, "right"));
1733
+ } else cells2.push(pad("\u2014", cols.find((c) => c.label !== "Provider").width + 2, "right"));
1734
+ }
1735
+ if (hasErrors) cells2.push(` ${red}FAIL${reset}`);
1736
+ console.log(` ${cells2.join("")}`);
1737
+ continue;
1738
+ }
1739
+ const avgScores = averageScores(successResults);
1740
+ const avgDetails = averageDetails(successResults);
1741
+ const latencyMs = average(successResults.map((r) => r.raw.latencyMs));
1742
+ const cells = [pad(provider, 24, "left")];
1743
+ for (const name of scorerNames) {
1744
+ if (name === "latency") {
1745
+ cells.push(pad(latencyMs !== void 0 ? `${Math.round(latencyMs)}ms` : "\u2014", 12, "right"));
1746
+ } else if (name === "cost") {
1747
+ cells.push(pad(formatCost(avgDetails.costUsd), 14, "right"));
1748
+ cells.push(pad(avgDetails.totalTokens !== void 0 ? `${avgDetails.totalTokens}` : "\u2014", 11, "right"));
1749
+ } else {
1750
+ const val = avgScores[name];
1751
+ if (val === void 0) cells.push(pad("\u2014", 10, "right"));
1752
+ else cells.push(pad(colorScore(val), 10 + colorLen(colorScore(val)), "right"));
1753
+ }
1754
+ }
1755
+ if (hasErrors) {
1756
+ const failCount = errorResults2.length;
1757
+ cells.push(failCount > 0 ? ` ${yellow}${failCount} err${reset}` : ` ${green}OK${reset}`);
1758
+ }
1759
+ console.log(` ${cells.join("")}`);
1760
+ }
1761
+ console.log("");
1762
+ }
1763
+ printSummary(results, providers);
1764
+ const errorResults = results.filter((r) => r.error);
1765
+ if (errorResults.length > 0) {
1766
+ console.log(` ${bold("Errors")}`);
1767
+ console.log(` ${dim("\u2500".repeat(70))}`);
1768
+ const seen = /* @__PURE__ */ new Set();
1769
+ for (const r of errorResults) {
1770
+ const key = `${r.providerId}::${r.error}`;
1771
+ if (seen.has(key)) continue;
1772
+ seen.add(key);
1773
+ const count = errorResults.filter((e) => e.providerId === r.providerId && e.error === r.error).length;
1774
+ const suffix = count > 1 ? ` (\xD7${count})` : "";
1775
+ console.log(` ${red}\u2717${reset} ${r.providerId}: ${r.error}${suffix}`);
1776
+ const hint = apiKeyHint(r.providerId, r.error ?? "");
1777
+ if (hint) console.log(` ${dim(hint)}`);
1778
+ }
1779
+ console.log("");
1780
+ }
1781
+ if (hasCost) {
1782
+ console.log(dim(` Costs estimated from OpenRouter pricing catalog. Run npx tsx scripts/update-pricing.ts to refresh.`));
1783
+ console.log("");
1784
+ }
1785
+ }
1786
+ function printSummary(results, providers) {
1787
+ const successResults = results.filter((r) => !r.error);
1788
+ if (successResults.length === 0) return;
1789
+ console.log(` ${dim("\u2500".repeat(70))}`);
1790
+ console.log(` ${bold("Summary")}`);
1791
+ console.log("");
1792
+ const single = providers.length === 1;
1793
+ const correctnessKey = successResults.some((r) => r.scores.some((s) => s.name === "llm-judge-correctness" && s.value >= 0)) ? "llm-judge-correctness" : "correctness";
1794
+ const byCorrectness = rankProviders(successResults, providers, correctnessKey);
1795
+ if (byCorrectness) {
1796
+ const label = single ? "Avg correctness" : `Most correct: ${bold(byCorrectness.id)} ${dim(providerLabel(byCorrectness.id))}`;
1797
+ console.log(` ${cyan}\u25C6${reset} ${label} (avg ${colorScore(byCorrectness.avg)})`);
1798
+ }
1799
+ const byLatency = providers.map((id) => {
1800
+ const runs = successResults.filter((r) => r.providerId === id);
1801
+ const avg = average(runs.map((r) => r.raw.latencyMs));
1802
+ return { id, avg: avg ?? Infinity };
1803
+ }).sort((a, b) => a.avg - b.avg)[0];
1804
+ if (byLatency && byLatency.avg !== Infinity) {
1805
+ const label = single ? "Avg latency" : `Fastest: ${bold(byLatency.id)} ${dim(providerLabel(byLatency.id))}`;
1806
+ console.log(` ${cyan}\u25C6${reset} ${label} (avg ${Math.round(byLatency.avg)}ms)`);
1807
+ }
1808
+ const byCost = providers.map((id) => {
1809
+ const runs = successResults.filter((r) => r.providerId === id);
1810
+ const costs = runs.map((r) => {
1811
+ const s = r.scores.find((s2) => s2.name === "cost");
1812
+ return s && s.value >= 0 ? s.value : void 0;
1813
+ }).filter((c) => c !== void 0);
1814
+ const avg = costs.length > 0 ? costs.reduce((a, b) => a + b, 0) / costs.length : void 0;
1815
+ return { id, avg };
1816
+ }).filter((p) => p.avg !== void 0).sort((a, b) => a.avg - b.avg)[0];
1817
+ if (byCost?.avg !== void 0) {
1818
+ const label = single ? "Avg cost" : `Cheapest: ${bold(byCost.id)} ${dim(providerLabel(byCost.id))}`;
1819
+ console.log(` ${cyan}\u25C6${reset} ${label} (avg ${formatCost(byCost.avg)})`);
1820
+ }
1821
+ console.log("");
1822
+ }
1823
+ function rankProviders(results, providers, scorerName) {
1824
+ const ranked = providers.map((id) => {
1825
+ const runs = results.filter((r) => r.providerId === id);
1826
+ const scores = runs.flatMap((r) => r.scores.filter((s) => s.name === scorerName && s.value >= 0)).map((s) => s.value);
1827
+ const avg = scores.length > 0 ? scores.reduce((a, b) => a + b, 0) / scores.length : void 0;
1828
+ return { id, avg };
1829
+ }).filter((p) => p.avg !== void 0).sort((a, b) => b.avg - a.avg);
1830
+ return ranked[0] ? { id: ranked[0].id, avg: ranked[0].avg } : void 0;
1831
+ }
1832
+ function averageScores(results) {
1833
+ const sums = {};
1834
+ const counts = {};
1835
+ for (const result of results) {
1836
+ for (const score of result.scores) {
1837
+ if (score.value < 0) continue;
1838
+ sums[score.name] = (sums[score.name] ?? 0) + score.value;
1839
+ counts[score.name] = (counts[score.name] ?? 0) + 1;
1840
+ }
1841
+ }
1842
+ const avgs = {};
1843
+ for (const name of Object.keys(sums)) {
1844
+ avgs[name] = sums[name] / counts[name];
1845
+ }
1846
+ return avgs;
1847
+ }
1848
+ function averageDetails(results) {
1849
+ let costSum = 0;
1850
+ let costCount = 0;
1851
+ let tokenSum = 0;
1852
+ let tokenCount = 0;
1853
+ for (const result of results) {
1854
+ const costScore = result.scores.find((s) => s.name === "cost");
1855
+ const details = costScore?.details;
1856
+ if (details?.estimatedUsd != null) {
1857
+ costSum += details.estimatedUsd;
1858
+ costCount++;
1859
+ }
1860
+ if (details?.totalTokens != null) {
1861
+ tokenSum += details.totalTokens;
1862
+ tokenCount++;
1863
+ }
1864
+ }
1865
+ return {
1866
+ costUsd: costCount > 0 ? costSum / costCount : void 0,
1867
+ totalTokens: tokenCount > 0 ? Math.round(tokenSum / tokenCount) : void 0
1868
+ };
1869
+ }
1870
+ function average(nums) {
1871
+ if (nums.length === 0) return void 0;
1872
+ return nums.reduce((a, b) => a + b, 0) / nums.length;
1873
+ }
1874
+ function formatCost(usd) {
1875
+ if (usd === void 0) return "\u2014";
1876
+ if (usd === 0) return "$0.00";
1877
+ if (usd >= 0.01) return `~$${usd.toFixed(2)}`;
1878
+ const digits = Math.max(4, -Math.floor(Math.log10(usd)) + 1);
1879
+ return `~$${usd.toFixed(digits).replace(/0+$/, "")}`;
1880
+ }
1881
+ function pad(str, width, align) {
1882
+ if (align === "right") return str.padStart(width);
1883
+ return str.padEnd(width);
1884
+ }
1885
+ function colorLen(str) {
1886
+ const stripped = str.replace(/\x1b\[[0-9;]*m/g, "");
1887
+ return str.length - stripped.length;
1888
+ }
1889
+ function apiKeyHint(providerId, error) {
1890
+ const lower = error.toLowerCase();
1891
+ const isAuthError = lower.includes("api key") || lower.includes("401") || lower.includes("unauthorized") || lower.includes("authentication") || lower.includes("incorrect api key") || lower.includes("apikey");
1892
+ if (!isAuthError) return void 0;
1893
+ const prefix = providerId.split("/")[0];
1894
+ switch (prefix) {
1895
+ case "openai":
1896
+ return "Set: export OPENAI_API_KEY=sk-...";
1897
+ case "azure":
1898
+ return "Set: export AZURE_OPENAI_API_KEY=... and AZURE_OPENAI_ENDPOINT=...";
1899
+ case "anthropic":
1900
+ return "Set: export ANTHROPIC_API_KEY=sk-ant-...";
1901
+ case "google":
1902
+ return "Set: export GOOGLE_API_KEY=...";
1903
+ default:
1904
+ return `Check the API key for ${providerId}`;
1905
+ }
1906
+ }
1907
+ function providerLabel(providerId) {
1908
+ const prefix = providerId.split("/")[0];
1909
+ switch (prefix) {
1910
+ case "azure":
1911
+ return "(OpenAI via Azure)";
1912
+ case "openai":
1913
+ return "(OpenAI)";
1914
+ case "anthropic":
1915
+ return "(Anthropic)";
1916
+ case "google":
1917
+ return "(Google)";
1918
+ case "mistral":
1919
+ return "(Mistral)";
1920
+ case "meta":
1921
+ return "(Meta)";
1922
+ case "deepseek":
1923
+ return "(DeepSeek)";
1924
+ case "cohere":
1925
+ return "(Cohere)";
1926
+ case "qwen":
1927
+ return "(Qwen)";
1928
+ case "xai":
1929
+ return "(xAI)";
1930
+ case "minimax":
1931
+ return "(MiniMax)";
1932
+ case "moonshot":
1933
+ return "(Moonshot / Kimi)";
1934
+ case "perplexity":
1935
+ return "(Perplexity)";
1936
+ case "amazon":
1937
+ return "(Amazon)";
1938
+ case "nvidia":
1939
+ return "(NVIDIA)";
1940
+ case "microsoft":
1941
+ return "(Microsoft)";
1942
+ case "ai21":
1943
+ return "(AI21 Labs)";
1944
+ case "bytedance":
1945
+ return "(ByteDance)";
1946
+ case "together":
1947
+ return "(Together AI)";
1948
+ case "fireworks":
1949
+ return "(Fireworks AI)";
1950
+ case "groq":
1951
+ return "(Groq)";
1952
+ case "cerebras":
1953
+ return "(Cerebras)";
1954
+ default:
1955
+ return `(${prefix})`;
1956
+ }
1957
+ }
1958
+
1959
+ // src/reporter/json.ts
1960
+ function jsonReporter(results) {
1961
+ return JSON.stringify(
1962
+ {
1963
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1964
+ summary: buildSummary(results),
1965
+ results
1966
+ },
1967
+ null,
1968
+ 2
1969
+ );
1970
+ }
1971
+ function buildSummary(results) {
1972
+ const tasks = [...new Set(results.map((r) => r.taskName))];
1973
+ const providers = [...new Set(results.map((r) => r.providerId))];
1974
+ return {
1975
+ totalBenchmarks: results.length,
1976
+ tasks: tasks.length,
1977
+ providers: providers.length,
1978
+ providerIds: providers,
1979
+ taskNames: tasks
1980
+ };
1981
+ }
1982
+
1983
+ // src/arena.ts
1984
+ function defineArena(config) {
1985
+ if (config.providers.length === 0) {
1986
+ throw new Error("At least one provider is required");
1987
+ }
1988
+ if (config.tasks.length === 0) {
1989
+ throw new Error("At least one task is required");
1990
+ }
1991
+ const scorerNames = config.scorers ?? ["latency", "cost", "correctness"];
1992
+ const scorerFns = resolveScorers(scorerNames, config.judgeModel);
1993
+ const runs = config.runs ?? 1;
1994
+ return {
1995
+ config,
1996
+ async run(options) {
1997
+ return runBenchmarks({
1998
+ providers: config.providers,
1999
+ tasks: config.tasks,
2000
+ scorers: scorerFns,
2001
+ runs,
2002
+ onResult: options?.onResult
2003
+ });
2004
+ }
2005
+ };
2006
+ }
2007
+
2008
+ // src/providers/openai.ts
2009
+ var import_openai2 = __toESM(require("openai"), 1);
2010
+ var import_zod_to_json_schema = require("zod-to-json-schema");
2011
+ function openai(model, options) {
2012
+ const client = new import_openai2.default({
2013
+ apiKey: options?.apiKey ?? process.env.OPENAI_API_KEY,
2014
+ baseURL: options?.baseURL
2015
+ });
2016
+ return makeProvider(`openai/${model}`, "OpenAI", model, client, model);
2017
+ }
2018
+ function openaiCompatible(options) {
2019
+ const apiKey = options.apiKey ?? (options.apiKeyEnv ? process.env[options.apiKeyEnv] : void 0) ?? "no-key";
2020
+ const client = new import_openai2.default({
2021
+ apiKey,
2022
+ baseURL: options.baseURL
2023
+ });
2024
+ if (options.free) {
2025
+ registerPricing(options.id, { inputPerToken: 0, outputPerToken: 0 });
2026
+ }
2027
+ return makeProvider(options.id, options.name, options.model, client, options.model, options.stripThinking);
2028
+ }
2029
+ function azureOpenai(model, options) {
2030
+ const deployment = options?.deployment ?? model;
2031
+ const client = new import_openai2.AzureOpenAI({
2032
+ apiKey: options?.apiKey ?? process.env.AZURE_OPENAI_API_KEY,
2033
+ endpoint: options?.endpoint ?? process.env.AZURE_OPENAI_ENDPOINT,
2034
+ apiVersion: options?.apiVersion ?? process.env.AZURE_OPENAI_API_VERSION ?? "2024-12-01-preview",
2035
+ deployment
2036
+ });
2037
+ return makeProvider(`azure/${model}`, "Azure OpenAI", model, client, deployment);
2038
+ }
2039
+ function makeProvider(id, name, model, client, requestModel, stripThinking) {
2040
+ return {
2041
+ id,
2042
+ name,
2043
+ model,
2044
+ async run(input) {
2045
+ const start = Date.now();
2046
+ const params = {
2047
+ model: requestModel,
2048
+ messages: [{ role: "user", content: input.prompt }]
2049
+ };
2050
+ if (input.schema) {
2051
+ params.response_format = { type: "json_object" };
2052
+ params.messages = [
2053
+ { role: "system", content: "Respond with valid JSON matching the requested schema." },
2054
+ ...params.messages
2055
+ ];
2056
+ }
2057
+ if (input.tools?.length) {
2058
+ params.tools = input.tools.map(toolDefToOpenAI);
2059
+ params.tool_choice = "auto";
2060
+ }
2061
+ const response = await client.chat.completions.create(params);
2062
+ let totalPromptTokens = response.usage?.prompt_tokens ?? 0;
2063
+ let totalCompletionTokens = response.usage?.completion_tokens ?? 0;
2064
+ const choice = response.choices[0];
2065
+ const toolCallsRaw = choice?.message?.tool_calls;
2066
+ const collectedToolCalls = [];
2067
+ let finalResponse = response;
2068
+ if (toolCallsRaw?.length && input.tools?.length) {
2069
+ const toolMessages = [
2070
+ ...params.messages,
2071
+ choice.message
2072
+ ];
2073
+ for (const tc of toolCallsRaw) {
2074
+ const toolDef = input.tools.find((t) => t.name === tc.function.name);
2075
+ let args;
2076
+ try {
2077
+ args = JSON.parse(tc.function.arguments);
2078
+ } catch {
2079
+ args = tc.function.arguments;
2080
+ }
2081
+ let result;
2082
+ if (toolDef?.handler) {
2083
+ result = await toolDef.handler(args);
2084
+ }
2085
+ collectedToolCalls.push({ name: tc.function.name, arguments: args, result });
2086
+ toolMessages.push({
2087
+ role: "tool",
2088
+ tool_call_id: tc.id,
2089
+ content: JSON.stringify(result ?? {})
2090
+ });
2091
+ }
2092
+ const followUp = await client.chat.completions.create({
2093
+ model: requestModel,
2094
+ messages: toolMessages
2095
+ });
2096
+ totalPromptTokens += followUp.usage?.prompt_tokens ?? 0;
2097
+ totalCompletionTokens += followUp.usage?.completion_tokens ?? 0;
2098
+ finalResponse = followUp;
2099
+ }
2100
+ const latencyMs = Date.now() - start;
2101
+ const finalChoice = finalResponse.choices[0];
2102
+ let rawContent = finalChoice?.message?.content ?? "";
2103
+ if (stripThinking) {
2104
+ rawContent = rawContent.replace(/<think>[\s\S]*?<\/think>\s*/, "");
2105
+ }
2106
+ let output = rawContent;
2107
+ if (input.schema) {
2108
+ try {
2109
+ output = JSON.parse(rawContent);
2110
+ } catch {
2111
+ }
2112
+ }
2113
+ return {
2114
+ output,
2115
+ usage: {
2116
+ promptTokens: totalPromptTokens || void 0,
2117
+ completionTokens: totalCompletionTokens || void 0
2118
+ },
2119
+ latencyMs,
2120
+ raw: finalResponse,
2121
+ toolCalls: collectedToolCalls.length > 0 ? collectedToolCalls : void 0
2122
+ };
2123
+ }
2124
+ };
2125
+ }
2126
+ function toolDefToOpenAI(tool) {
2127
+ return {
2128
+ type: "function",
2129
+ function: {
2130
+ name: tool.name,
2131
+ description: tool.description,
2132
+ parameters: (0, import_zod_to_json_schema.zodToJsonSchema)(tool.parameters, { target: "openAi" })
2133
+ }
2134
+ };
2135
+ }
2136
+
2137
+ // src/providers/anthropic.ts
2138
+ var import_sdk = __toESM(require("@anthropic-ai/sdk"), 1);
2139
+ function anthropic(model, options) {
2140
+ const client = new import_sdk.default({
2141
+ apiKey: options?.apiKey ?? process.env.ANTHROPIC_API_KEY
2142
+ });
2143
+ const maxTokens = options?.maxTokens ?? 1024;
2144
+ return {
2145
+ id: `anthropic/${model}`,
2146
+ name: "Anthropic",
2147
+ model,
2148
+ async run(input) {
2149
+ const start = Date.now();
2150
+ const systemMessage = input.schema ? "Respond with valid JSON matching the requested schema." : void 0;
2151
+ const response = await client.messages.create({
2152
+ model,
2153
+ max_tokens: maxTokens,
2154
+ system: systemMessage,
2155
+ messages: [{ role: "user", content: input.prompt }]
2156
+ });
2157
+ const latencyMs = Date.now() - start;
2158
+ const textBlock = response.content.find((b) => b.type === "text");
2159
+ const rawContent = textBlock?.type === "text" ? textBlock.text : "";
2160
+ let output = rawContent;
2161
+ if (input.schema) {
2162
+ try {
2163
+ output = JSON.parse(rawContent);
2164
+ } catch {
2165
+ }
2166
+ }
2167
+ return {
2168
+ output,
2169
+ usage: {
2170
+ promptTokens: response.usage.input_tokens,
2171
+ completionTokens: response.usage.output_tokens
2172
+ },
2173
+ latencyMs,
2174
+ raw: response
2175
+ };
2176
+ }
2177
+ };
2178
+ }
2179
+
2180
+ // src/providers/gemini.ts
2181
+ var import_openai3 = __toESM(require("openai"), 1);
2182
+ function gemini(model, options) {
2183
+ const apiKey = options?.apiKey ?? process.env.GOOGLE_API_KEY;
2184
+ if (!apiKey) {
2185
+ throw new Error(
2186
+ `Missing API key for google/${model}. Set GOOGLE_API_KEY or pass apiKey option.`
2187
+ );
2188
+ }
2189
+ const client = new import_openai3.default({
2190
+ apiKey,
2191
+ baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/"
2192
+ });
2193
+ return makeProvider(`google/${model}`, "Google AI", model, client, model);
2194
+ }
2195
+ // Annotate the CommonJS export names for ESM import in node:
2196
+ 0 && (module.exports = {
2197
+ anthropic,
2198
+ azureOpenai,
2199
+ consoleReporter,
2200
+ defineArena,
2201
+ gemini,
2202
+ jsonReporter,
2203
+ openai,
2204
+ openaiCompatible,
2205
+ registerPricing
2206
+ });
2207
+ //# sourceMappingURL=index.cjs.map