localarena 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "localarena",
3
- "version": "0.1.0",
4
- "description": "Local-first pairwise evaluation, deterministic scheduling, and Elo ranking.",
3
+ "version": "0.2.0",
4
+ "description": "Live multi-provider model evaluation, scoring, reports, and Elo.",
5
5
  "keywords": [
6
6
  "evaluation",
7
7
  "elo",
@@ -31,17 +31,21 @@
31
31
  "default": "./javascript/src/index.js"
32
32
  },
33
33
  "./schema/localarena-v1.schema.json": "./schema/localarena-v1.schema.json",
34
+ "./schema/localarena-evaluation-config-v1.schema.json": "./schema/localarena-evaluation-config-v1.schema.json",
35
+ "./schema/localarena-evaluation-run-v1.schema.json": "./schema/localarena-evaluation-run-v1.schema.json",
34
36
  "./package.json": "./package.json"
35
37
  },
36
38
  "files": [
37
39
  "javascript/src",
38
40
  "schema",
41
+ "docs",
42
+ "examples",
39
43
  "README.md",
40
44
  "CHANGELOG.md",
41
45
  "LICENSE"
42
46
  ],
43
47
  "scripts": {
44
- "check": "node --check javascript/src/index.js",
48
+ "check": "node --check javascript/src/index.js && node --check javascript/src/providers.js && node --check javascript/src/tasks.js && node --check javascript/src/evaluation.js && node --check javascript/src/report.js",
45
49
  "test": "node --test",
46
50
  "pack:check": "npm pack --dry-run"
47
51
  },
@@ -0,0 +1,612 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/maziyarpanahi/localarena/blob/main/schema/localarena-evaluation-config-v1.schema.json",
4
+ "title": "LocalArena evaluation configuration v1",
5
+ "description": "Configuration accepted by the LocalArena live evaluation command.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "models",
10
+ "tasks"
11
+ ],
12
+ "properties": {
13
+ "$schema": {
14
+ "type": "string",
15
+ "minLength": 1,
16
+ "format": "uri-reference"
17
+ },
18
+ "name": {
19
+ "$ref": "#/$defs/nonEmptyString"
20
+ },
21
+ "concurrency": {
22
+ "type": "integer",
23
+ "minimum": 1
24
+ },
25
+ "repetitions": {
26
+ "type": "integer",
27
+ "minimum": 1
28
+ },
29
+ "include_content": {
30
+ "type": "boolean",
31
+ "default": false,
32
+ "description": "Opt in to retaining task, answer, score, and error content."
33
+ },
34
+ "models": {
35
+ "type": "array",
36
+ "minItems": 1,
37
+ "items": {
38
+ "$ref": "#/$defs/model"
39
+ },
40
+ "contains": {
41
+ "anyOf": [
42
+ {
43
+ "not": {
44
+ "required": [
45
+ "judge_only"
46
+ ]
47
+ }
48
+ },
49
+ {
50
+ "required": [
51
+ "judge_only"
52
+ ],
53
+ "properties": {
54
+ "judge_only": {
55
+ "const": false
56
+ }
57
+ }
58
+ }
59
+ ]
60
+ }
61
+ },
62
+ "tasks": {
63
+ "type": "array",
64
+ "minItems": 1,
65
+ "items": {
66
+ "$ref": "#/$defs/task"
67
+ }
68
+ }
69
+ },
70
+ "$defs": {
71
+ "nonEmptyString": {
72
+ "type": "string",
73
+ "minLength": 1,
74
+ "pattern": "\\S"
75
+ },
76
+ "safeInteger": {
77
+ "type": "integer",
78
+ "minimum": -9007199254740991,
79
+ "maximum": 9007199254740991
80
+ },
81
+ "environmentVariable": {
82
+ "type": "string",
83
+ "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
84
+ },
85
+ "baseUrl": {
86
+ "type": "string",
87
+ "format": "uri",
88
+ "allOf": [
89
+ {
90
+ "pattern": "^https?://[^\\s]+$"
91
+ },
92
+ {
93
+ "not": {
94
+ "pattern": "[?#]"
95
+ }
96
+ },
97
+ {
98
+ "not": {
99
+ "pattern": "^https?://[^/]*@"
100
+ }
101
+ }
102
+ ]
103
+ },
104
+ "headerName": {
105
+ "type": "string",
106
+ "pattern": "^[!#$%&'*+.^_`|~0-9A-Za-z-]+$",
107
+ "not": {
108
+ "pattern": "^(?:[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Ll][Ee][Nn][Gg][Tt][Hh]|[Cc][Oo][Nn][Tt][Ee][Nn][Tt]-[Tt][Yy][Pp][Ee]|[Aa][Cc][Cc][Ee][Pp][Tt]|[Hh][Oo][Ss][Tt])$"
109
+ }
110
+ },
111
+ "literalHeaderName": {
112
+ "allOf": [
113
+ {
114
+ "$ref": "#/$defs/headerName"
115
+ },
116
+ {
117
+ "not": {
118
+ "pattern": "(?:[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]|[Aa][Pp][Ii][-_]?[Kk][Ee][Yy]|[Tt][Oo][Kk][Ee][Nn]|[Ss][Ee][Cc][Rr][Ee][Tt]|[Cc][Oo][Oo][Kk][Ii][Ee])"
119
+ }
120
+ }
121
+ ]
122
+ },
123
+ "headerValue": {
124
+ "type": "string",
125
+ "pattern": "^[^\\r\\n]*$"
126
+ },
127
+ "literalHeaders": {
128
+ "type": "object",
129
+ "propertyNames": {
130
+ "$ref": "#/$defs/literalHeaderName"
131
+ },
132
+ "additionalProperties": {
133
+ "$ref": "#/$defs/headerValue"
134
+ }
135
+ },
136
+ "environmentHeaders": {
137
+ "type": "object",
138
+ "propertyNames": {
139
+ "$ref": "#/$defs/headerName"
140
+ },
141
+ "additionalProperties": {
142
+ "$ref": "#/$defs/environmentVariable"
143
+ }
144
+ },
145
+ "requestPolicy": {
146
+ "type": "object",
147
+ "additionalProperties": false,
148
+ "properties": {
149
+ "timeout": {
150
+ "type": "number",
151
+ "exclusiveMinimum": 0
152
+ },
153
+ "max_attempts": {
154
+ "type": "integer",
155
+ "minimum": 1,
156
+ "maximum": 10,
157
+ "default": 1,
158
+ "description": "One attempt by default; values above one explicitly enable retries."
159
+ },
160
+ "backoff_seconds": {
161
+ "type": "number",
162
+ "minimum": 0
163
+ },
164
+ "max_backoff_seconds": {
165
+ "type": "number",
166
+ "minimum": 0
167
+ },
168
+ "max_retry_after_seconds": {
169
+ "type": "number",
170
+ "minimum": 0
171
+ },
172
+ "max_response_bytes": {
173
+ "type": "integer",
174
+ "minimum": 1
175
+ }
176
+ }
177
+ },
178
+ "modelParameters": {
179
+ "type": "object",
180
+ "additionalProperties": false,
181
+ "properties": {
182
+ "max_tokens": {
183
+ "oneOf": [
184
+ {
185
+ "type": "integer",
186
+ "minimum": 1,
187
+ "maximum": 9007199254740991
188
+ },
189
+ {
190
+ "type": "null"
191
+ }
192
+ ]
193
+ },
194
+ "temperature": {
195
+ "oneOf": [
196
+ {
197
+ "type": "number",
198
+ "minimum": 0,
199
+ "maximum": 2
200
+ },
201
+ {
202
+ "type": "null"
203
+ }
204
+ ]
205
+ },
206
+ "seed": {
207
+ "oneOf": [
208
+ {
209
+ "$ref": "#/$defs/safeInteger"
210
+ },
211
+ {
212
+ "type": "null"
213
+ }
214
+ ]
215
+ },
216
+ "stop": {
217
+ "type": "array",
218
+ "items": {
219
+ "type": "string",
220
+ "minLength": 1
221
+ }
222
+ },
223
+ "extra_body": {
224
+ "type": "object",
225
+ "propertyNames": {
226
+ "not": {
227
+ "enum": [
228
+ "model",
229
+ "messages",
230
+ "stream",
231
+ "max_tokens",
232
+ "max_completion_tokens",
233
+ "temperature",
234
+ "seed",
235
+ "stop"
236
+ ]
237
+ }
238
+ }
239
+ }
240
+ }
241
+ },
242
+ "model": {
243
+ "type": "object",
244
+ "additionalProperties": false,
245
+ "required": [
246
+ "name",
247
+ "provider",
248
+ "model"
249
+ ],
250
+ "properties": {
251
+ "name": {
252
+ "$ref": "#/$defs/nonEmptyString"
253
+ },
254
+ "provider": {
255
+ "enum": [
256
+ "llamacpp",
257
+ "ollama",
258
+ "lmstudio",
259
+ "openrouter",
260
+ "openai",
261
+ "custom"
262
+ ]
263
+ },
264
+ "base_url": {
265
+ "oneOf": [
266
+ {
267
+ "$ref": "#/$defs/baseUrl"
268
+ },
269
+ {
270
+ "type": "null"
271
+ }
272
+ ]
273
+ },
274
+ "api_key_env": {
275
+ "oneOf": [
276
+ {
277
+ "$ref": "#/$defs/environmentVariable"
278
+ },
279
+ {
280
+ "type": "null"
281
+ }
282
+ ]
283
+ },
284
+ "judge_only": {
285
+ "type": "boolean",
286
+ "default": false,
287
+ "description": "Make this target available to model_judge evaluators without evaluating it as a contestant."
288
+ },
289
+ "headers": {
290
+ "$ref": "#/$defs/literalHeaders"
291
+ },
292
+ "headers_env": {
293
+ "$ref": "#/$defs/environmentHeaders"
294
+ },
295
+ "policy": {
296
+ "$ref": "#/$defs/requestPolicy"
297
+ },
298
+ "model": {
299
+ "$ref": "#/$defs/nonEmptyString"
300
+ },
301
+ "parameters": {
302
+ "$ref": "#/$defs/modelParameters"
303
+ }
304
+ },
305
+ "allOf": [
306
+ {
307
+ "if": {
308
+ "properties": {
309
+ "provider": {
310
+ "const": "custom"
311
+ }
312
+ }
313
+ },
314
+ "then": {
315
+ "required": [
316
+ "base_url"
317
+ ],
318
+ "properties": {
319
+ "base_url": {
320
+ "$ref": "#/$defs/baseUrl"
321
+ }
322
+ }
323
+ }
324
+ }
325
+ ]
326
+ },
327
+ "message": {
328
+ "type": "object",
329
+ "additionalProperties": false,
330
+ "required": [
331
+ "role",
332
+ "content"
333
+ ],
334
+ "properties": {
335
+ "role": {
336
+ "enum": [
337
+ "system",
338
+ "user",
339
+ "assistant"
340
+ ]
341
+ },
342
+ "content": {
343
+ "type": "string"
344
+ }
345
+ }
346
+ },
347
+ "task": {
348
+ "type": "object",
349
+ "additionalProperties": false,
350
+ "required": [
351
+ "id"
352
+ ],
353
+ "properties": {
354
+ "id": {
355
+ "$ref": "#/$defs/nonEmptyString"
356
+ },
357
+ "prompt": {
358
+ "type": "string"
359
+ },
360
+ "system": {
361
+ "type": [
362
+ "string",
363
+ "null"
364
+ ]
365
+ },
366
+ "messages": {
367
+ "type": "array",
368
+ "minItems": 1,
369
+ "items": {
370
+ "$ref": "#/$defs/message"
371
+ }
372
+ },
373
+ "evaluator": {
374
+ "oneOf": [
375
+ {
376
+ "type": "null"
377
+ },
378
+ {
379
+ "$ref": "#/$defs/evaluator"
380
+ }
381
+ ]
382
+ },
383
+ "metadata": {
384
+ "type": "object"
385
+ }
386
+ },
387
+ "oneOf": [
388
+ {
389
+ "required": [
390
+ "prompt"
391
+ ],
392
+ "not": {
393
+ "required": [
394
+ "messages"
395
+ ]
396
+ }
397
+ },
398
+ {
399
+ "required": [
400
+ "messages"
401
+ ],
402
+ "not": {
403
+ "anyOf": [
404
+ {
405
+ "required": [
406
+ "prompt"
407
+ ]
408
+ },
409
+ {
410
+ "required": [
411
+ "system"
412
+ ]
413
+ }
414
+ ]
415
+ }
416
+ }
417
+ ]
418
+ },
419
+ "evaluator": {
420
+ "oneOf": [
421
+ {
422
+ "$ref": "#/$defs/noneEvaluator"
423
+ },
424
+ {
425
+ "$ref": "#/$defs/exactEvaluator"
426
+ },
427
+ {
428
+ "$ref": "#/$defs/containsEvaluator"
429
+ },
430
+ {
431
+ "$ref": "#/$defs/regexEvaluator"
432
+ },
433
+ {
434
+ "$ref": "#/$defs/jsonEvaluator"
435
+ },
436
+ {
437
+ "$ref": "#/$defs/numericEvaluator"
438
+ },
439
+ {
440
+ "$ref": "#/$defs/modelJudgeEvaluator"
441
+ }
442
+ ]
443
+ },
444
+ "noneEvaluator": {
445
+ "type": "object",
446
+ "additionalProperties": false,
447
+ "required": [
448
+ "type"
449
+ ],
450
+ "properties": {
451
+ "type": {
452
+ "const": "none"
453
+ }
454
+ }
455
+ },
456
+ "exactEvaluator": {
457
+ "type": "object",
458
+ "additionalProperties": false,
459
+ "required": [
460
+ "type",
461
+ "expected"
462
+ ],
463
+ "properties": {
464
+ "type": {
465
+ "const": "exact"
466
+ },
467
+ "expected": {
468
+ "type": "string"
469
+ },
470
+ "strip": {
471
+ "type": "boolean"
472
+ },
473
+ "ignore_case": {
474
+ "type": "boolean"
475
+ }
476
+ }
477
+ },
478
+ "containsEvaluator": {
479
+ "type": "object",
480
+ "additionalProperties": false,
481
+ "required": [
482
+ "type",
483
+ "expected"
484
+ ],
485
+ "properties": {
486
+ "type": {
487
+ "const": "contains"
488
+ },
489
+ "expected": {
490
+ "oneOf": [
491
+ {
492
+ "type": "string",
493
+ "minLength": 1
494
+ },
495
+ {
496
+ "type": "array",
497
+ "minItems": 1,
498
+ "items": {
499
+ "type": "string",
500
+ "minLength": 1
501
+ }
502
+ }
503
+ ]
504
+ },
505
+ "mode": {
506
+ "enum": [
507
+ "all",
508
+ "any"
509
+ ]
510
+ },
511
+ "ignore_case": {
512
+ "type": "boolean"
513
+ }
514
+ }
515
+ },
516
+ "regexEvaluator": {
517
+ "type": "object",
518
+ "additionalProperties": false,
519
+ "required": [
520
+ "type",
521
+ "pattern"
522
+ ],
523
+ "properties": {
524
+ "type": {
525
+ "const": "regex"
526
+ },
527
+ "pattern": {
528
+ "$ref": "#/$defs/nonEmptyString"
529
+ },
530
+ "ignore_case": {
531
+ "type": "boolean"
532
+ },
533
+ "full_match": {
534
+ "type": "boolean"
535
+ }
536
+ }
537
+ },
538
+ "jsonEvaluator": {
539
+ "type": "object",
540
+ "additionalProperties": false,
541
+ "required": [
542
+ "type"
543
+ ],
544
+ "properties": {
545
+ "type": {
546
+ "const": "json"
547
+ },
548
+ "expected": {},
549
+ "compare": {
550
+ "type": "boolean"
551
+ }
552
+ }
553
+ },
554
+ "numericEvaluator": {
555
+ "type": "object",
556
+ "additionalProperties": false,
557
+ "required": [
558
+ "type",
559
+ "expected"
560
+ ],
561
+ "properties": {
562
+ "type": {
563
+ "const": "numeric"
564
+ },
565
+ "expected": {
566
+ "type": "number"
567
+ },
568
+ "tolerance": {
569
+ "type": "number",
570
+ "minimum": 0
571
+ }
572
+ }
573
+ },
574
+ "modelJudgeEvaluator": {
575
+ "type": "object",
576
+ "additionalProperties": false,
577
+ "required": [
578
+ "type",
579
+ "model"
580
+ ],
581
+ "properties": {
582
+ "type": {
583
+ "const": "model_judge"
584
+ },
585
+ "model": {
586
+ "$ref": "#/$defs/nonEmptyString"
587
+ },
588
+ "rubric": {
589
+ "$ref": "#/$defs/nonEmptyString"
590
+ },
591
+ "reference_answer": {
592
+ "type": [
593
+ "string",
594
+ "null"
595
+ ]
596
+ },
597
+ "pass_threshold": {
598
+ "oneOf": [
599
+ {
600
+ "type": "number",
601
+ "minimum": 0,
602
+ "maximum": 1
603
+ },
604
+ {
605
+ "type": "null"
606
+ }
607
+ ]
608
+ }
609
+ }
610
+ }
611
+ }
612
+ }