rohitsar567 commited on
Commit
81703e5
Β·
verified Β·
1 Parent(s): 5c6f7e8

Deploy: Stack A (NIM brain + Maverick judge + Sarvam voice). D-019.

Browse files
Files changed (2) hide show
  1. 40-data/llm_health.json +188 -188
  2. backend/main.py +90 -23
40-data/llm_health.json CHANGED
@@ -1,44 +1,44 @@
1
  {
2
- "updated_at": "2026-05-15T01:54:30Z",
3
  "models": {
4
  "qwen/qwen3-next-80b-a3b-instruct": {
5
  "model": "qwen/qwen3-next-80b-a3b-instruct",
6
  "status": "healthy",
7
- "last_success_at": "2026-05-15T01:54:30Z",
8
  "last_failure_at": null,
9
  "last_error": null,
10
- "latency_ms": 771,
11
  "consecutive_failures": 0,
12
- "tested_at": "2026-05-15T01:54:30Z",
13
  "probe_history": [
14
  {
15
  "ok": true,
16
- "latency_ms": 285,
17
- "ts": "2026-05-15T01:40:22Z",
18
  "src": "probe"
19
  },
20
  {
21
  "ok": true,
22
- "latency_ms": 289,
23
- "ts": "2026-05-15T01:41:07Z",
24
  "src": "probe"
25
  },
26
  {
27
  "ok": true,
28
- "latency_ms": 2573,
29
- "ts": "2026-05-15T01:46:37Z",
30
  "src": "probe"
31
  },
32
  {
33
  "ok": true,
34
- "latency_ms": 1208,
35
- "ts": "2026-05-15T01:52:30Z",
36
  "src": "probe"
37
  },
38
  {
39
  "ok": true,
40
- "latency_ms": 771,
41
- "ts": "2026-05-15T01:54:30Z",
42
  "src": "probe"
43
  }
44
  ],
@@ -53,40 +53,40 @@
53
  "model": "qwen/qwen3.5-122b-a10b",
54
  "status": "down",
55
  "last_success_at": null,
56
- "last_failure_at": "2026-05-15T01:54:30Z",
57
  "last_error": "timeout",
58
  "latency_ms": null,
59
- "consecutive_failures": 18,
60
- "tested_at": "2026-05-15T01:54:30Z",
61
  "probe_history": [
62
  {
63
  "ok": false,
64
  "latency_ms": 8001,
65
- "ts": "2026-05-15T01:40:22Z",
66
  "src": "probe"
67
  },
68
  {
69
  "ok": false,
70
  "latency_ms": 8002,
71
- "ts": "2026-05-15T01:41:07Z",
72
  "src": "probe"
73
  },
74
  {
75
  "ok": false,
76
- "latency_ms": 8001,
77
- "ts": "2026-05-15T01:46:37Z",
78
  "src": "probe"
79
  },
80
  {
81
  "ok": false,
82
- "latency_ms": 8001,
83
- "ts": "2026-05-15T01:52:30Z",
84
  "src": "probe"
85
  },
86
  {
87
  "ok": false,
88
  "latency_ms": 8002,
89
- "ts": "2026-05-15T01:54:30Z",
90
  "src": "probe"
91
  }
92
  ],
@@ -101,40 +101,40 @@
101
  "model": "openai/gpt-oss-120b",
102
  "status": "down",
103
  "last_success_at": null,
104
- "last_failure_at": "2026-05-15T01:54:30Z",
105
  "last_error": "empty_content",
106
  "latency_ms": null,
107
- "consecutive_failures": 18,
108
- "tested_at": "2026-05-15T01:54:30Z",
109
  "probe_history": [
110
  {
111
  "ok": false,
112
- "latency_ms": 261,
113
- "ts": "2026-05-15T01:40:22Z",
114
  "src": "probe"
115
  },
116
  {
117
  "ok": false,
118
- "latency_ms": 406,
119
- "ts": "2026-05-15T01:41:07Z",
120
  "src": "probe"
121
  },
122
  {
123
  "ok": false,
124
- "latency_ms": 473,
125
- "ts": "2026-05-15T01:46:37Z",
126
  "src": "probe"
127
  },
128
  {
129
  "ok": false,
130
- "latency_ms": 253,
131
- "ts": "2026-05-15T01:52:30Z",
132
  "src": "probe"
133
  },
134
  {
135
  "ok": false,
136
- "latency_ms": 311,
137
- "ts": "2026-05-15T01:54:30Z",
138
  "src": "probe"
139
  }
140
  ],
@@ -148,41 +148,41 @@
148
  "mistralai/mistral-large-3-675b-instruct-2512": {
149
  "model": "mistralai/mistral-large-3-675b-instruct-2512",
150
  "status": "healthy",
151
- "last_success_at": "2026-05-15T01:54:30Z",
152
- "last_failure_at": "2026-05-15T01:52:30Z",
153
  "last_error": null,
154
- "latency_ms": 617,
155
  "consecutive_failures": 0,
156
- "tested_at": "2026-05-15T01:54:30Z",
157
  "probe_history": [
158
  {
159
- "ok": true,
160
- "latency_ms": 782,
161
- "ts": "2026-05-15T01:40:22Z",
162
  "src": "probe"
163
  },
164
  {
165
  "ok": true,
166
- "latency_ms": 615,
167
- "ts": "2026-05-15T01:41:07Z",
168
  "src": "probe"
169
  },
170
  {
171
- "ok": true,
172
- "latency_ms": 449,
173
- "ts": "2026-05-15T01:46:37Z",
174
  "src": "probe"
175
  },
176
  {
177
- "ok": false,
178
- "latency_ms": 8002,
179
- "ts": "2026-05-15T01:52:30Z",
180
  "src": "probe"
181
  },
182
  {
183
  "ok": true,
184
- "latency_ms": 617,
185
- "ts": "2026-05-15T01:54:30Z",
186
  "src": "probe"
187
  }
188
  ],
@@ -195,42 +195,42 @@
195
  },
196
  "nvidia/llama-3.3-nemotron-super-49b-v1.5": {
197
  "model": "nvidia/llama-3.3-nemotron-super-49b-v1.5",
198
- "status": "degraded",
199
- "last_success_at": "2026-05-15T01:54:30Z",
200
  "last_failure_at": "2026-05-15T01:24:45Z",
201
  "last_error": null,
202
- "latency_ms": 5838,
203
  "consecutive_failures": 0,
204
- "tested_at": "2026-05-15T01:54:30Z",
205
  "probe_history": [
206
  {
207
  "ok": true,
208
- "latency_ms": 385,
209
- "ts": "2026-05-15T01:40:22Z",
210
  "src": "probe"
211
  },
212
  {
213
  "ok": true,
214
- "latency_ms": 304,
215
- "ts": "2026-05-15T01:41:07Z",
216
  "src": "probe"
217
  },
218
  {
219
  "ok": true,
220
- "latency_ms": 307,
221
- "ts": "2026-05-15T01:46:37Z",
222
  "src": "probe"
223
  },
224
  {
225
  "ok": true,
226
- "latency_ms": 349,
227
- "ts": "2026-05-15T01:52:30Z",
228
  "src": "probe"
229
  },
230
  {
231
  "ok": true,
232
- "latency_ms": 5838,
233
- "ts": "2026-05-15T01:54:30Z",
234
  "src": "probe"
235
  }
236
  ],
@@ -244,41 +244,41 @@
244
  "meta/llama-3.3-70b-instruct": {
245
  "model": "meta/llama-3.3-70b-instruct",
246
  "status": "healthy",
247
- "last_success_at": "2026-05-15T01:54:30Z",
248
  "last_failure_at": "2026-05-15T01:41:07Z",
249
  "last_error": null,
250
- "latency_ms": 3890,
251
  "consecutive_failures": 0,
252
- "tested_at": "2026-05-15T01:54:30Z",
253
  "probe_history": [
254
  {
255
- "ok": false,
256
- "latency_ms": 8003,
257
- "ts": "2026-05-15T01:40:22Z",
258
  "src": "probe"
259
  },
260
  {
261
- "ok": false,
262
- "latency_ms": 34,
263
- "ts": "2026-05-15T01:41:07Z",
264
  "src": "probe"
265
  },
266
  {
267
  "ok": true,
268
- "latency_ms": 210,
269
- "ts": "2026-05-15T01:46:37Z",
270
  "src": "probe"
271
  },
272
  {
273
  "ok": true,
274
- "latency_ms": 212,
275
- "ts": "2026-05-15T01:52:30Z",
276
  "src": "probe"
277
  },
278
  {
279
  "ok": true,
280
- "latency_ms": 3890,
281
- "ts": "2026-05-15T01:54:30Z",
282
  "src": "probe"
283
  }
284
  ],
@@ -293,40 +293,40 @@
293
  "model": "deepseek-ai/deepseek-v4-pro",
294
  "status": "down",
295
  "last_success_at": null,
296
- "last_failure_at": "2026-05-15T01:54:30Z",
297
  "last_error": "timeout",
298
  "latency_ms": null,
299
- "consecutive_failures": 18,
300
- "tested_at": "2026-05-15T01:54:30Z",
301
  "probe_history": [
302
  {
303
  "ok": false,
304
- "latency_ms": 8059,
305
- "ts": "2026-05-15T01:40:22Z",
306
  "src": "probe"
307
  },
308
  {
309
  "ok": false,
310
  "latency_ms": 8002,
311
- "ts": "2026-05-15T01:41:07Z",
312
  "src": "probe"
313
  },
314
  {
315
  "ok": false,
316
  "latency_ms": 8001,
317
- "ts": "2026-05-15T01:46:37Z",
318
  "src": "probe"
319
  },
320
  {
321
  "ok": false,
322
- "latency_ms": 8003,
323
- "ts": "2026-05-15T01:52:30Z",
324
  "src": "probe"
325
  },
326
  {
327
  "ok": false,
328
- "latency_ms": 8002,
329
- "ts": "2026-05-15T01:54:30Z",
330
  "src": "probe"
331
  }
332
  ],
@@ -341,40 +341,40 @@
341
  "model": "nvidia/nemotron-3-nano-30b-a3b",
342
  "status": "down",
343
  "last_success_at": null,
344
- "last_failure_at": "2026-05-15T01:54:30Z",
345
  "last_error": "empty_content",
346
  "latency_ms": null,
347
- "consecutive_failures": 18,
348
- "tested_at": "2026-05-15T01:54:30Z",
349
  "probe_history": [
350
  {
351
  "ok": false,
352
- "latency_ms": 271,
353
- "ts": "2026-05-15T01:40:22Z",
354
  "src": "probe"
355
  },
356
  {
357
  "ok": false,
358
- "latency_ms": 275,
359
- "ts": "2026-05-15T01:41:07Z",
360
  "src": "probe"
361
  },
362
  {
363
  "ok": false,
364
- "latency_ms": 268,
365
- "ts": "2026-05-15T01:46:37Z",
366
  "src": "probe"
367
  },
368
  {
369
  "ok": false,
370
- "latency_ms": 263,
371
- "ts": "2026-05-15T01:52:30Z",
372
  "src": "probe"
373
  },
374
  {
375
  "ok": false,
376
- "latency_ms": 276,
377
- "ts": "2026-05-15T01:54:30Z",
378
  "src": "probe"
379
  }
380
  ],
@@ -389,40 +389,40 @@
389
  "model": "deepseek-ai/deepseek-v4-flash",
390
  "status": "down",
391
  "last_success_at": null,
392
- "last_failure_at": "2026-05-15T01:54:30Z",
393
  "last_error": "timeout",
394
  "latency_ms": null,
395
- "consecutive_failures": 18,
396
- "tested_at": "2026-05-15T01:54:30Z",
397
  "probe_history": [
398
  {
399
  "ok": false,
400
- "latency_ms": 8002,
401
- "ts": "2026-05-15T01:40:22Z",
402
  "src": "probe"
403
  },
404
  {
405
  "ok": false,
406
- "latency_ms": 8002,
407
- "ts": "2026-05-15T01:41:07Z",
408
  "src": "probe"
409
  },
410
  {
411
  "ok": false,
412
- "latency_ms": 8002,
413
- "ts": "2026-05-15T01:46:37Z",
414
  "src": "probe"
415
  },
416
  {
417
  "ok": false,
418
- "latency_ms": 8004,
419
- "ts": "2026-05-15T01:52:30Z",
420
  "src": "probe"
421
  },
422
  {
423
  "ok": false,
424
- "latency_ms": 8003,
425
- "ts": "2026-05-15T01:54:30Z",
426
  "src": "probe"
427
  }
428
  ],
@@ -437,40 +437,40 @@
437
  "model": "moonshotai/kimi-k2-instruct-0905",
438
  "status": "down",
439
  "last_success_at": null,
440
- "last_failure_at": "2026-05-15T01:54:30Z",
441
  "last_error": "http_404",
442
  "latency_ms": null,
443
- "consecutive_failures": 18,
444
- "tested_at": "2026-05-15T01:54:30Z",
445
  "probe_history": [
446
  {
447
  "ok": false,
448
  "latency_ms": 84,
449
- "ts": "2026-05-15T01:40:22Z",
450
  "src": "probe"
451
  },
452
  {
453
  "ok": false,
454
- "latency_ms": 94,
455
- "ts": "2026-05-15T01:41:07Z",
456
  "src": "probe"
457
  },
458
  {
459
  "ok": false,
460
- "latency_ms": 84,
461
- "ts": "2026-05-15T01:46:37Z",
462
  "src": "probe"
463
  },
464
  {
465
  "ok": false,
466
- "latency_ms": 84,
467
- "ts": "2026-05-15T01:52:30Z",
468
  "src": "probe"
469
  },
470
  {
471
  "ok": false,
472
- "latency_ms": 81,
473
- "ts": "2026-05-15T01:54:30Z",
474
  "src": "probe"
475
  }
476
  ],
@@ -485,40 +485,40 @@
485
  "model": "minimaxai/minimax-m2.5",
486
  "status": "down",
487
  "last_success_at": null,
488
- "last_failure_at": "2026-05-15T01:54:30Z",
489
  "last_error": "http_410",
490
  "latency_ms": null,
491
- "consecutive_failures": 18,
492
- "tested_at": "2026-05-15T01:54:30Z",
493
  "probe_history": [
494
  {
495
  "ok": false,
496
- "latency_ms": 32,
497
- "ts": "2026-05-15T01:40:22Z",
498
  "src": "probe"
499
  },
500
  {
501
  "ok": false,
502
- "latency_ms": 33,
503
- "ts": "2026-05-15T01:41:07Z",
504
  "src": "probe"
505
  },
506
  {
507
  "ok": false,
508
- "latency_ms": 31,
509
- "ts": "2026-05-15T01:46:37Z",
510
  "src": "probe"
511
  },
512
  {
513
  "ok": false,
514
- "latency_ms": 29,
515
- "ts": "2026-05-15T01:52:30Z",
516
  "src": "probe"
517
  },
518
  {
519
  "ok": false,
520
  "latency_ms": 31,
521
- "ts": "2026-05-15T01:54:30Z",
522
  "src": "probe"
523
  }
524
  ],
@@ -532,41 +532,41 @@
532
  "meta/llama-4-maverick-17b-128e-instruct": {
533
  "model": "meta/llama-4-maverick-17b-128e-instruct",
534
  "status": "healthy",
535
- "last_success_at": "2026-05-15T01:54:30Z",
536
  "last_failure_at": "2026-05-14T01:03:07Z",
537
  "last_error": null,
538
- "latency_ms": 247,
539
  "consecutive_failures": 0,
540
- "tested_at": "2026-05-15T01:54:30Z",
541
  "probe_history": [
542
  {
543
  "ok": true,
544
- "latency_ms": 313,
545
- "ts": "2026-05-15T01:40:22Z",
546
  "src": "probe"
547
  },
548
  {
549
  "ok": true,
550
- "latency_ms": 314,
551
- "ts": "2026-05-15T01:41:07Z",
552
  "src": "probe"
553
  },
554
  {
555
  "ok": true,
556
- "latency_ms": 309,
557
- "ts": "2026-05-15T01:46:37Z",
558
  "src": "probe"
559
  },
560
  {
561
  "ok": true,
562
- "latency_ms": 205,
563
- "ts": "2026-05-15T01:52:30Z",
564
  "src": "probe"
565
  },
566
  {
567
  "ok": true,
568
- "latency_ms": 247,
569
- "ts": "2026-05-15T01:54:30Z",
570
  "src": "probe"
571
  }
572
  ],
@@ -579,42 +579,42 @@
579
  },
580
  "openrouter:openai/gpt-oss-120b": {
581
  "model": "openrouter:openai/gpt-oss-120b",
582
- "status": "degraded",
583
  "last_success_at": "2026-05-15T01:46:37Z",
584
- "last_failure_at": "2026-05-15T01:54:30Z",
585
  "last_error": "empty_content",
586
  "latency_ms": 1349,
587
- "consecutive_failures": 2,
588
- "tested_at": "2026-05-15T01:54:30Z",
589
  "probe_history": [
590
  {
591
- "ok": true,
592
- "latency_ms": 4642,
593
- "ts": "2026-05-15T01:40:22Z",
594
  "src": "probe"
595
  },
596
  {
597
- "ok": true,
598
- "latency_ms": 5821,
599
- "ts": "2026-05-15T01:41:07Z",
600
  "src": "probe"
601
  },
602
  {
603
- "ok": true,
604
- "latency_ms": 1349,
605
- "ts": "2026-05-15T01:46:37Z",
606
  "src": "probe"
607
  },
608
  {
609
  "ok": false,
610
- "latency_ms": 1635,
611
- "ts": "2026-05-15T01:52:30Z",
612
  "src": "probe"
613
  },
614
  {
615
  "ok": false,
616
- "latency_ms": 856,
617
- "ts": "2026-05-15T01:54:30Z",
618
  "src": "probe"
619
  }
620
  ],
@@ -622,47 +622,47 @@
622
  "credits_remaining": 0.0,
623
  "credits_unit": "usd_balance",
624
  "credits_reset_at": null,
625
- "credits_observed_at": 5158.700559583,
626
  "credits_low_water": 0.05
627
  },
628
  "groq:llama-3.3-70b-versatile": {
629
  "model": "groq:llama-3.3-70b-versatile",
630
  "status": "healthy",
631
- "last_success_at": "2026-05-15T01:54:30Z",
632
  "last_failure_at": null,
633
  "last_error": null,
634
- "latency_ms": 261,
635
  "consecutive_failures": 0,
636
- "tested_at": "2026-05-15T01:54:30Z",
637
  "probe_history": [
638
  {
639
  "ok": true,
640
- "latency_ms": 285,
641
- "ts": "2026-05-15T01:40:22Z",
642
  "src": "probe"
643
  },
644
  {
645
  "ok": true,
646
- "latency_ms": 258,
647
- "ts": "2026-05-15T01:41:07Z",
648
  "src": "probe"
649
  },
650
  {
651
  "ok": true,
652
- "latency_ms": 157,
653
- "ts": "2026-05-15T01:46:37Z",
654
  "src": "probe"
655
  },
656
  {
657
  "ok": true,
658
- "latency_ms": 247,
659
- "ts": "2026-05-15T01:52:30Z",
660
  "src": "probe"
661
  },
662
  {
663
  "ok": true,
664
- "latency_ms": 261,
665
- "ts": "2026-05-15T01:54:30Z",
666
  "src": "probe"
667
  }
668
  ],
 
1
  {
2
+ "updated_at": "2026-05-15T02:03:36Z",
3
  "models": {
4
  "qwen/qwen3-next-80b-a3b-instruct": {
5
  "model": "qwen/qwen3-next-80b-a3b-instruct",
6
  "status": "healthy",
7
+ "last_success_at": "2026-05-15T02:03:36Z",
8
  "last_failure_at": null,
9
  "last_error": null,
10
+ "latency_ms": 772,
11
  "consecutive_failures": 0,
12
+ "tested_at": "2026-05-15T02:03:36Z",
13
  "probe_history": [
14
  {
15
  "ok": true,
16
+ "latency_ms": 1208,
17
+ "ts": "2026-05-15T01:52:30Z",
18
  "src": "probe"
19
  },
20
  {
21
  "ok": true,
22
+ "latency_ms": 771,
23
+ "ts": "2026-05-15T01:54:30Z",
24
  "src": "probe"
25
  },
26
  {
27
  "ok": true,
28
+ "latency_ms": 996,
29
+ "ts": "2026-05-15T02:00:06Z",
30
  "src": "probe"
31
  },
32
  {
33
  "ok": true,
34
+ "latency_ms": 277,
35
+ "ts": "2026-05-15T02:01:50Z",
36
  "src": "probe"
37
  },
38
  {
39
  "ok": true,
40
+ "latency_ms": 772,
41
+ "ts": "2026-05-15T02:03:36Z",
42
  "src": "probe"
43
  }
44
  ],
 
53
  "model": "qwen/qwen3.5-122b-a10b",
54
  "status": "down",
55
  "last_success_at": null,
56
+ "last_failure_at": "2026-05-15T02:03:36Z",
57
  "last_error": "timeout",
58
  "latency_ms": null,
59
+ "consecutive_failures": 21,
60
+ "tested_at": "2026-05-15T02:03:36Z",
61
  "probe_history": [
62
  {
63
  "ok": false,
64
  "latency_ms": 8001,
65
+ "ts": "2026-05-15T01:52:30Z",
66
  "src": "probe"
67
  },
68
  {
69
  "ok": false,
70
  "latency_ms": 8002,
71
+ "ts": "2026-05-15T01:54:30Z",
72
  "src": "probe"
73
  },
74
  {
75
  "ok": false,
76
+ "latency_ms": 8002,
77
+ "ts": "2026-05-15T02:00:06Z",
78
  "src": "probe"
79
  },
80
  {
81
  "ok": false,
82
+ "latency_ms": 8002,
83
+ "ts": "2026-05-15T02:01:50Z",
84
  "src": "probe"
85
  },
86
  {
87
  "ok": false,
88
  "latency_ms": 8002,
89
+ "ts": "2026-05-15T02:03:36Z",
90
  "src": "probe"
91
  }
92
  ],
 
101
  "model": "openai/gpt-oss-120b",
102
  "status": "down",
103
  "last_success_at": null,
104
+ "last_failure_at": "2026-05-15T02:03:36Z",
105
  "last_error": "empty_content",
106
  "latency_ms": null,
107
+ "consecutive_failures": 21,
108
+ "tested_at": "2026-05-15T02:03:36Z",
109
  "probe_history": [
110
  {
111
  "ok": false,
112
+ "latency_ms": 253,
113
+ "ts": "2026-05-15T01:52:30Z",
114
  "src": "probe"
115
  },
116
  {
117
  "ok": false,
118
+ "latency_ms": 311,
119
+ "ts": "2026-05-15T01:54:30Z",
120
  "src": "probe"
121
  },
122
  {
123
  "ok": false,
124
+ "latency_ms": 1109,
125
+ "ts": "2026-05-15T02:00:06Z",
126
  "src": "probe"
127
  },
128
  {
129
  "ok": false,
130
+ "latency_ms": 428,
131
+ "ts": "2026-05-15T02:01:50Z",
132
  "src": "probe"
133
  },
134
  {
135
  "ok": false,
136
+ "latency_ms": 271,
137
+ "ts": "2026-05-15T02:03:36Z",
138
  "src": "probe"
139
  }
140
  ],
 
148
  "mistralai/mistral-large-3-675b-instruct-2512": {
149
  "model": "mistralai/mistral-large-3-675b-instruct-2512",
150
  "status": "healthy",
151
+ "last_success_at": "2026-05-15T02:03:36Z",
152
+ "last_failure_at": "2026-05-15T02:00:06Z",
153
  "last_error": null,
154
+ "latency_ms": 514,
155
  "consecutive_failures": 0,
156
+ "tested_at": "2026-05-15T02:03:36Z",
157
  "probe_history": [
158
  {
159
+ "ok": false,
160
+ "latency_ms": 8002,
161
+ "ts": "2026-05-15T01:52:30Z",
162
  "src": "probe"
163
  },
164
  {
165
  "ok": true,
166
+ "latency_ms": 617,
167
+ "ts": "2026-05-15T01:54:30Z",
168
  "src": "probe"
169
  },
170
  {
171
+ "ok": false,
172
+ "latency_ms": 8003,
173
+ "ts": "2026-05-15T02:00:06Z",
174
  "src": "probe"
175
  },
176
  {
177
+ "ok": true,
178
+ "latency_ms": 611,
179
+ "ts": "2026-05-15T02:01:50Z",
180
  "src": "probe"
181
  },
182
  {
183
  "ok": true,
184
+ "latency_ms": 514,
185
+ "ts": "2026-05-15T02:03:36Z",
186
  "src": "probe"
187
  }
188
  ],
 
195
  },
196
  "nvidia/llama-3.3-nemotron-super-49b-v1.5": {
197
  "model": "nvidia/llama-3.3-nemotron-super-49b-v1.5",
198
+ "status": "healthy",
199
+ "last_success_at": "2026-05-15T02:03:36Z",
200
  "last_failure_at": "2026-05-15T01:24:45Z",
201
  "last_error": null,
202
+ "latency_ms": 315,
203
  "consecutive_failures": 0,
204
+ "tested_at": "2026-05-15T02:03:36Z",
205
  "probe_history": [
206
  {
207
  "ok": true,
208
+ "latency_ms": 349,
209
+ "ts": "2026-05-15T01:52:30Z",
210
  "src": "probe"
211
  },
212
  {
213
  "ok": true,
214
+ "latency_ms": 5838,
215
+ "ts": "2026-05-15T01:54:30Z",
216
  "src": "probe"
217
  },
218
  {
219
  "ok": true,
220
+ "latency_ms": 496,
221
+ "ts": "2026-05-15T02:00:06Z",
222
  "src": "probe"
223
  },
224
  {
225
  "ok": true,
226
+ "latency_ms": 1538,
227
+ "ts": "2026-05-15T02:01:50Z",
228
  "src": "probe"
229
  },
230
  {
231
  "ok": true,
232
+ "latency_ms": 315,
233
+ "ts": "2026-05-15T02:03:36Z",
234
  "src": "probe"
235
  }
236
  ],
 
244
  "meta/llama-3.3-70b-instruct": {
245
  "model": "meta/llama-3.3-70b-instruct",
246
  "status": "healthy",
247
+ "last_success_at": "2026-05-15T02:03:36Z",
248
  "last_failure_at": "2026-05-15T01:41:07Z",
249
  "last_error": null,
250
+ "latency_ms": 698,
251
  "consecutive_failures": 0,
252
+ "tested_at": "2026-05-15T02:03:36Z",
253
  "probe_history": [
254
  {
255
+ "ok": true,
256
+ "latency_ms": 212,
257
+ "ts": "2026-05-15T01:52:30Z",
258
  "src": "probe"
259
  },
260
  {
261
+ "ok": true,
262
+ "latency_ms": 3890,
263
+ "ts": "2026-05-15T01:54:30Z",
264
  "src": "probe"
265
  },
266
  {
267
  "ok": true,
268
+ "latency_ms": 535,
269
+ "ts": "2026-05-15T02:00:06Z",
270
  "src": "probe"
271
  },
272
  {
273
  "ok": true,
274
+ "latency_ms": 2558,
275
+ "ts": "2026-05-15T02:01:50Z",
276
  "src": "probe"
277
  },
278
  {
279
  "ok": true,
280
+ "latency_ms": 698,
281
+ "ts": "2026-05-15T02:03:36Z",
282
  "src": "probe"
283
  }
284
  ],
 
293
  "model": "deepseek-ai/deepseek-v4-pro",
294
  "status": "down",
295
  "last_success_at": null,
296
+ "last_failure_at": "2026-05-15T02:03:36Z",
297
  "last_error": "timeout",
298
  "latency_ms": null,
299
+ "consecutive_failures": 21,
300
+ "tested_at": "2026-05-15T02:03:36Z",
301
  "probe_history": [
302
  {
303
  "ok": false,
304
+ "latency_ms": 8003,
305
+ "ts": "2026-05-15T01:52:30Z",
306
  "src": "probe"
307
  },
308
  {
309
  "ok": false,
310
  "latency_ms": 8002,
311
+ "ts": "2026-05-15T01:54:30Z",
312
  "src": "probe"
313
  },
314
  {
315
  "ok": false,
316
  "latency_ms": 8001,
317
+ "ts": "2026-05-15T02:00:06Z",
318
  "src": "probe"
319
  },
320
  {
321
  "ok": false,
322
+ "latency_ms": 8002,
323
+ "ts": "2026-05-15T02:01:50Z",
324
  "src": "probe"
325
  },
326
  {
327
  "ok": false,
328
+ "latency_ms": 8003,
329
+ "ts": "2026-05-15T02:03:36Z",
330
  "src": "probe"
331
  }
332
  ],
 
341
  "model": "nvidia/nemotron-3-nano-30b-a3b",
342
  "status": "down",
343
  "last_success_at": null,
344
+ "last_failure_at": "2026-05-15T02:03:36Z",
345
  "last_error": "empty_content",
346
  "latency_ms": null,
347
+ "consecutive_failures": 21,
348
+ "tested_at": "2026-05-15T02:03:36Z",
349
  "probe_history": [
350
  {
351
  "ok": false,
352
+ "latency_ms": 263,
353
+ "ts": "2026-05-15T01:52:30Z",
354
  "src": "probe"
355
  },
356
  {
357
  "ok": false,
358
+ "latency_ms": 276,
359
+ "ts": "2026-05-15T01:54:30Z",
360
  "src": "probe"
361
  },
362
  {
363
  "ok": false,
364
+ "latency_ms": 277,
365
+ "ts": "2026-05-15T02:00:06Z",
366
  "src": "probe"
367
  },
368
  {
369
  "ok": false,
370
+ "latency_ms": 265,
371
+ "ts": "2026-05-15T02:01:50Z",
372
  "src": "probe"
373
  },
374
  {
375
  "ok": false,
376
+ "latency_ms": 283,
377
+ "ts": "2026-05-15T02:03:36Z",
378
  "src": "probe"
379
  }
380
  ],
 
389
  "model": "deepseek-ai/deepseek-v4-flash",
390
  "status": "down",
391
  "last_success_at": null,
392
+ "last_failure_at": "2026-05-15T02:03:36Z",
393
  "last_error": "timeout",
394
  "latency_ms": null,
395
+ "consecutive_failures": 21,
396
+ "tested_at": "2026-05-15T02:03:36Z",
397
  "probe_history": [
398
  {
399
  "ok": false,
400
+ "latency_ms": 8004,
401
+ "ts": "2026-05-15T01:52:30Z",
402
  "src": "probe"
403
  },
404
  {
405
  "ok": false,
406
+ "latency_ms": 8003,
407
+ "ts": "2026-05-15T01:54:30Z",
408
  "src": "probe"
409
  },
410
  {
411
  "ok": false,
412
+ "latency_ms": 8003,
413
+ "ts": "2026-05-15T02:00:06Z",
414
  "src": "probe"
415
  },
416
  {
417
  "ok": false,
418
+ "latency_ms": 8003,
419
+ "ts": "2026-05-15T02:01:50Z",
420
  "src": "probe"
421
  },
422
  {
423
  "ok": false,
424
+ "latency_ms": 8001,
425
+ "ts": "2026-05-15T02:03:36Z",
426
  "src": "probe"
427
  }
428
  ],
 
437
  "model": "moonshotai/kimi-k2-instruct-0905",
438
  "status": "down",
439
  "last_success_at": null,
440
+ "last_failure_at": "2026-05-15T02:03:36Z",
441
  "last_error": "http_404",
442
  "latency_ms": null,
443
+ "consecutive_failures": 21,
444
+ "tested_at": "2026-05-15T02:03:36Z",
445
  "probe_history": [
446
  {
447
  "ok": false,
448
  "latency_ms": 84,
449
+ "ts": "2026-05-15T01:52:30Z",
450
  "src": "probe"
451
  },
452
  {
453
  "ok": false,
454
+ "latency_ms": 81,
455
+ "ts": "2026-05-15T01:54:30Z",
456
  "src": "probe"
457
  },
458
  {
459
  "ok": false,
460
+ "latency_ms": 89,
461
+ "ts": "2026-05-15T02:00:06Z",
462
  "src": "probe"
463
  },
464
  {
465
  "ok": false,
466
+ "latency_ms": 91,
467
+ "ts": "2026-05-15T02:01:50Z",
468
  "src": "probe"
469
  },
470
  {
471
  "ok": false,
472
+ "latency_ms": 91,
473
+ "ts": "2026-05-15T02:03:36Z",
474
  "src": "probe"
475
  }
476
  ],
 
485
  "model": "minimaxai/minimax-m2.5",
486
  "status": "down",
487
  "last_success_at": null,
488
+ "last_failure_at": "2026-05-15T02:03:36Z",
489
  "last_error": "http_410",
490
  "latency_ms": null,
491
+ "consecutive_failures": 21,
492
+ "tested_at": "2026-05-15T02:03:36Z",
493
  "probe_history": [
494
  {
495
  "ok": false,
496
+ "latency_ms": 29,
497
+ "ts": "2026-05-15T01:52:30Z",
498
  "src": "probe"
499
  },
500
  {
501
  "ok": false,
502
+ "latency_ms": 31,
503
+ "ts": "2026-05-15T01:54:30Z",
504
  "src": "probe"
505
  },
506
  {
507
  "ok": false,
508
+ "latency_ms": 30,
509
+ "ts": "2026-05-15T02:00:06Z",
510
  "src": "probe"
511
  },
512
  {
513
  "ok": false,
514
+ "latency_ms": 31,
515
+ "ts": "2026-05-15T02:01:50Z",
516
  "src": "probe"
517
  },
518
  {
519
  "ok": false,
520
  "latency_ms": 31,
521
+ "ts": "2026-05-15T02:03:36Z",
522
  "src": "probe"
523
  }
524
  ],
 
532
  "meta/llama-4-maverick-17b-128e-instruct": {
533
  "model": "meta/llama-4-maverick-17b-128e-instruct",
534
  "status": "healthy",
535
+ "last_success_at": "2026-05-15T02:03:36Z",
536
  "last_failure_at": "2026-05-14T01:03:07Z",
537
  "last_error": null,
538
+ "latency_ms": 214,
539
  "consecutive_failures": 0,
540
+ "tested_at": "2026-05-15T02:03:36Z",
541
  "probe_history": [
542
  {
543
  "ok": true,
544
+ "latency_ms": 205,
545
+ "ts": "2026-05-15T01:52:30Z",
546
  "src": "probe"
547
  },
548
  {
549
  "ok": true,
550
+ "latency_ms": 247,
551
+ "ts": "2026-05-15T01:54:30Z",
552
  "src": "probe"
553
  },
554
  {
555
  "ok": true,
556
+ "latency_ms": 206,
557
+ "ts": "2026-05-15T02:00:06Z",
558
  "src": "probe"
559
  },
560
  {
561
  "ok": true,
562
+ "latency_ms": 309,
563
+ "ts": "2026-05-15T02:01:50Z",
564
  "src": "probe"
565
  },
566
  {
567
  "ok": true,
568
+ "latency_ms": 214,
569
+ "ts": "2026-05-15T02:03:36Z",
570
  "src": "probe"
571
  }
572
  ],
 
579
  },
580
  "openrouter:openai/gpt-oss-120b": {
581
  "model": "openrouter:openai/gpt-oss-120b",
582
+ "status": "down",
583
  "last_success_at": "2026-05-15T01:46:37Z",
584
+ "last_failure_at": "2026-05-15T02:03:36Z",
585
  "last_error": "empty_content",
586
  "latency_ms": 1349,
587
+ "consecutive_failures": 5,
588
+ "tested_at": "2026-05-15T02:03:36Z",
589
  "probe_history": [
590
  {
591
+ "ok": false,
592
+ "latency_ms": 1635,
593
+ "ts": "2026-05-15T01:52:30Z",
594
  "src": "probe"
595
  },
596
  {
597
+ "ok": false,
598
+ "latency_ms": 856,
599
+ "ts": "2026-05-15T01:54:30Z",
600
  "src": "probe"
601
  },
602
  {
603
+ "ok": false,
604
+ "latency_ms": 883,
605
+ "ts": "2026-05-15T02:00:06Z",
606
  "src": "probe"
607
  },
608
  {
609
  "ok": false,
610
+ "latency_ms": 497,
611
+ "ts": "2026-05-15T02:01:50Z",
612
  "src": "probe"
613
  },
614
  {
615
  "ok": false,
616
+ "latency_ms": 497,
617
+ "ts": "2026-05-15T02:03:36Z",
618
  "src": "probe"
619
  }
620
  ],
 
622
  "credits_remaining": 0.0,
623
  "credits_unit": "usd_balance",
624
  "credits_reset_at": null,
625
+ "credits_observed_at": 5714.690950541,
626
  "credits_low_water": 0.05
627
  },
628
  "groq:llama-3.3-70b-versatile": {
629
  "model": "groq:llama-3.3-70b-versatile",
630
  "status": "healthy",
631
+ "last_success_at": "2026-05-15T02:03:36Z",
632
  "last_failure_at": null,
633
  "last_error": null,
634
+ "latency_ms": 252,
635
  "consecutive_failures": 0,
636
+ "tested_at": "2026-05-15T02:03:36Z",
637
  "probe_history": [
638
  {
639
  "ok": true,
640
+ "latency_ms": 247,
641
+ "ts": "2026-05-15T01:52:30Z",
642
  "src": "probe"
643
  },
644
  {
645
  "ok": true,
646
+ "latency_ms": 261,
647
+ "ts": "2026-05-15T01:54:30Z",
648
  "src": "probe"
649
  },
650
  {
651
  "ok": true,
652
+ "latency_ms": 306,
653
+ "ts": "2026-05-15T02:00:06Z",
654
  "src": "probe"
655
  },
656
  {
657
  "ok": true,
658
+ "latency_ms": 309,
659
+ "ts": "2026-05-15T02:01:50Z",
660
  "src": "probe"
661
  },
662
  {
663
  "ok": true,
664
+ "latency_ms": 252,
665
+ "ts": "2026-05-15T02:03:36Z",
666
  "src": "probe"
667
  }
668
  ],
backend/main.py CHANGED
@@ -569,27 +569,91 @@ async def coverage():
569
  # policy -> source_url (verified at download time)
570
  policy_urls: dict[tuple[str, str], str] = {}
571
  by_insurer: dict[str, dict] = {}
572
- if total > 0:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
573
  try:
574
- res = coll.get(limit=10000, include=["metadatas"])
575
- for m in res.get("metadatas", []):
576
- slug = m.get("insurer_slug", "unknown")
577
- # KI-129 (2026-05-15) β€” profile chunks live in the same
578
- # collection as policies (KI-118 design β€” they get retrieval-
579
- # boosted as USER CONTEXT inline with policy text), but they
580
- # must NEVER count as a user-facing insurer or policy. Skip.
581
- if slug == "profile" or m.get("doc_type") == "profile":
582
- continue
583
- name = m.get("policy_name", "")
584
- url = m.get("source_url", "")
585
- if slug not in by_insurer:
586
- by_insurer[slug] = {"policies": set(), "chunks": 0}
587
- by_insurer[slug]["policies"].add(name)
588
- by_insurer[slug]["chunks"] += 1
589
- if url and (slug, name) not in policy_urls:
590
- policy_urls[(slug, name)] = url
591
  except Exception:
592
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
593
 
594
  insurers_out = []
595
  total_policies = 0
@@ -599,19 +663,22 @@ async def coverage():
599
  # and cited in chat answers β€” they just don't show in the marketplace.
600
  if slug == "regulatory":
601
  continue
602
- policy_names = sorted(info["policies"])
603
- total_policies += len(policy_names)
 
 
 
604
  name, home_url = insurer_meta.get(slug, (slug, ""))
605
  sample_entries = [
606
  PolicyEntry(name=p, source_url=policy_urls.get((slug, p), ""))
607
- for p in policy_names[:8]
608
  ]
609
  insurers_out.append(
610
  InsurerCoverage(
611
  slug=slug,
612
  name=name,
613
  home_url=home_url,
614
- policy_count=len(policy_names),
615
  sample_policies=sample_entries,
616
  )
617
  )
 
569
  # policy -> source_url (verified at download time)
570
  policy_urls: dict[tuple[str, str], str] = {}
571
  by_insurer: dict[str, dict] = {}
572
+
573
+ # KI-135 (2026-05-15) β€” count policies the SAME way /api/policies/all
574
+ # does (extracted/*.json + curated-facts pass-2) so the marketplace badge
575
+ # ALWAYS matches the marketplace card count. Previously this loop read
576
+ # Chroma metadata, which under-counted by ~20 because ~15 curated-facts
577
+ # policies (Activ One, Optima Secure, Reassure 2/3, Health Guard Gold,
578
+ # etc.) are legitimate distinct products that have no Chroma chunks yet,
579
+ # plus ~5 display-name mismatches collapsed two policies into one. After
580
+ # this refactor: badge = cards = 158 / 19.
581
+ # KI-129 + KI-130 invariants still hold (profile + regulatory excluded).
582
+ import json as _json
583
+ _DOCTYPE_RANK_COV = {"wordings": 0, "prospectus": 1, "cis": 2, "brochure": 3}
584
+ _doctype_of_cov = lambda stem: stem.rsplit("__", 1)[1] if "__" in stem else ""
585
+ _product_key_of_cov = lambda pid: pid.rsplit("__", 1)[0] if "__" in pid else pid
586
+
587
+ curated_facts = _load_curated_facts()
588
+ sorted_files = sorted(
589
+ settings.EXTRACTED_DIR.glob("*.json"),
590
+ key=lambda fp: (_DOCTYPE_RANK_COV.get(_doctype_of_cov(fp.stem), 99), fp.stem),
591
+ )
592
+ seen_product_keys: set[str] = set()
593
+ seen_policy_ids: set[str] = set()
594
+
595
+ # by_insurer entries:
596
+ # products: set of product_keys (matches /api/policies/all card count)
597
+ # names: ordered dict of policy_NAME -> first product_key (for sample display)
598
+ # KI-135 (2026-05-15) β€” track product_keys (not names) for counting so the
599
+ # ~1 within-insurer policy_name collision (e.g. new-india Floater listed
600
+ # as both extracted + curated_facts) doesn't collapse the count below the
601
+ # marketplace card count. Both representations are still distinct products.
602
+
603
+ # Pass 1: extracted JSONs (KI-133 dedup by product_key β€” wordings wins)
604
+ for fp in sorted_files:
605
  try:
606
+ data = _json.loads(fp.read_text())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
607
  except Exception:
608
+ continue
609
+ pid = data.get("policy_id", fp.stem)
610
+ seen_policy_ids.add(pid)
611
+ slug = data.get("insurer_slug", "")
612
+ if slug == "regulatory":
613
+ continue
614
+ pkey = _product_key_of_cov(pid)
615
+ if pkey in seen_product_keys:
616
+ continue
617
+ seen_product_keys.add(pkey)
618
+ name = data.get("policy_name", "") or pid
619
+ url = data.get("source_pdf_url", "")
620
+ if slug not in by_insurer:
621
+ by_insurer[slug] = {"products": set(), "names": [], "chunks": 0}
622
+ by_insurer[slug]["products"].add(pkey)
623
+ if name not in by_insurer[slug]["names"]:
624
+ by_insurer[slug]["names"].append(name)
625
+ by_insurer[slug]["chunks"] += 1
626
+ if url and (slug, name) not in policy_urls:
627
+ policy_urls[(slug, name)] = url
628
+
629
+ # Pass 2: curated-facts policies that have no extracted counterpart
630
+ for curated_pid, data in curated_facts.items():
631
+ if curated_pid != data.get("policy_id", curated_pid):
632
+ continue # permutation alias
633
+ if curated_pid in seen_policy_ids:
634
+ continue
635
+ if any(eid.startswith(curated_pid + "__") for eid in seen_policy_ids):
636
+ continue
637
+ seen_policy_ids.add(curated_pid)
638
+ slug = data.get("insurer_slug", "")
639
+ if slug == "regulatory":
640
+ continue
641
+ # Curated entries don't have a __doctype suffix, so use the full
642
+ # policy_id as the product_key.
643
+ pkey = curated_pid
644
+ if pkey in seen_product_keys:
645
+ continue
646
+ seen_product_keys.add(pkey)
647
+ name = data.get("policy_name", "") or curated_pid
648
+ url = data.get("source_pdf_url", "")
649
+ if slug not in by_insurer:
650
+ by_insurer[slug] = {"products": set(), "names": [], "chunks": 0}
651
+ by_insurer[slug]["products"].add(pkey)
652
+ if name not in by_insurer[slug]["names"]:
653
+ by_insurer[slug]["names"].append(name)
654
+ by_insurer[slug]["chunks"] += 1
655
+ if url and (slug, name) not in policy_urls:
656
+ policy_urls[(slug, name)] = url
657
 
658
  insurers_out = []
659
  total_policies = 0
 
663
  # and cited in chat answers β€” they just don't show in the marketplace.
664
  if slug == "regulatory":
665
  continue
666
+ # KI-135 β€” count by product_key set (matches /api/policies/all); use
667
+ # the names list for the sample display ordered by first occurrence.
668
+ product_count = len(info["products"])
669
+ sample_names = sorted(info["names"])[:8]
670
+ total_policies += product_count
671
  name, home_url = insurer_meta.get(slug, (slug, ""))
672
  sample_entries = [
673
  PolicyEntry(name=p, source_url=policy_urls.get((slug, p), ""))
674
+ for p in sample_names
675
  ]
676
  insurers_out.append(
677
  InsurerCoverage(
678
  slug=slug,
679
  name=name,
680
  home_url=home_url,
681
+ policy_count=product_count,
682
  sample_policies=sample_entries,
683
  )
684
  )