free-coding-models 0.5.59 โ 0.5.61
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/README.md +32 -0
- package/bin/free-coding-models.js +31 -0
- package/changelog/v0.5.60.md +54 -0
- package/changelog/v0.5.61.md +65 -0
- package/package.json +6 -2
- package/src/core/extended-benchmarks.js +421 -0
- package/src/core/model-merger.js +155 -0
- package/src/core/models-dev-fetcher.js +210 -0
- package/src/core/models-dev-index.js +311 -0
- package/src/core/models-drift.js +296 -0
- package/src/core/router-daemon.js +96 -0
- package/src/core/runtime-telemetry.js +541 -0
- package/src/core/utils.js +29 -0
- package/src/data/benchmarks.json +302 -0
- package/src/tui/app.js +103 -0
- package/src/tui/cli-help.js +2 -0
- package/src/tui/key-handler.js +80 -0
- package/src/tui/render-table.js +38 -2
- package/src/tui/tui-state.js +9 -0
- package/web/dist/assets/{index-C_ZdUGrS.js โ index-4IyXp-vf.js} +2 -2
- package/web/dist/index.html +1 -1
- package/web/server.js +39 -0
- package/web/src/components/router/RouterView.jsx +34 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_meta": {
|
|
3
|
+
"schemaVersion": 1,
|
|
4
|
+
"lastUpdated": "2026-07-25",
|
|
5
|
+
"source": "Artificial Analysis + curated manual overlay",
|
|
6
|
+
"notes": "Curated seed dataset for ~30 well-known models. Refreshed by scripts/update-benchmarks.mjs before each release. Fields with null are not yet measured."
|
|
7
|
+
},
|
|
8
|
+
"deepseek-ai/deepseek-v3.2": {
|
|
9
|
+
"codingIndex": 65.4, "mathIndex": 70.2, "agenticIndex": 58.0, "reasoningIndex": 68.5,
|
|
10
|
+
"mmluPro": 75.3, "gpqa": 52.0, "hle": 8.4, "contextWindow": 160000,
|
|
11
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
12
|
+
"lastUpdated": "2026-07-20", "originalModel": "DeepSeek V3.2"
|
|
13
|
+
},
|
|
14
|
+
"deepseek-ai/deepseek-v4-pro": {
|
|
15
|
+
"codingIndex": 81.2, "mathIndex": 84.5, "agenticIndex": 74.8, "reasoningIndex": 80.1,
|
|
16
|
+
"mmluPro": 86.4, "gpqa": 65.7, "hle": 14.2, "contextWindow": 1000000,
|
|
17
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
18
|
+
"lastUpdated": "2026-07-20", "originalModel": "DeepSeek V4 Pro"
|
|
19
|
+
},
|
|
20
|
+
"deepseek-ai/deepseek-v4-flash": {
|
|
21
|
+
"codingIndex": 78.9, "mathIndex": 80.1, "agenticIndex": 71.5, "reasoningIndex": 77.0,
|
|
22
|
+
"mmluPro": 83.2, "gpqa": 60.4, "hle": 12.8, "contextWindow": 1000000,
|
|
23
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
24
|
+
"lastUpdated": "2026-07-20", "originalModel": "DeepSeek V4 Flash"
|
|
25
|
+
},
|
|
26
|
+
"deepseek-ai/deepseek-r1": {
|
|
27
|
+
"codingIndex": 52.0, "mathIndex": 90.4, "agenticIndex": 48.5, "reasoningIndex": 78.6,
|
|
28
|
+
"mmluPro": 84.0, "gpqa": 71.5, "hle": 9.9, "contextWindow": 128000,
|
|
29
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
30
|
+
"lastUpdated": "2026-07-20", "originalModel": "DeepSeek R1"
|
|
31
|
+
},
|
|
32
|
+
"deepseek/deepseek-r1": {
|
|
33
|
+
"codingIndex": 52.0, "mathIndex": 90.4, "agenticIndex": 48.5, "reasoningIndex": 78.6,
|
|
34
|
+
"mmluPro": 84.0, "gpqa": 71.5, "hle": 9.9, "contextWindow": 128000,
|
|
35
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
36
|
+
"lastUpdated": "2026-07-20", "originalModel": "DeepSeek R1"
|
|
37
|
+
},
|
|
38
|
+
"DeepSeek-V3.1": {
|
|
39
|
+
"codingIndex": 68.0, "mathIndex": 73.0, "agenticIndex": 60.5, "reasoningIndex": 70.0,
|
|
40
|
+
"mmluPro": 76.5, "gpqa": 53.2, "hle": 9.1, "contextWindow": 128000,
|
|
41
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
42
|
+
"lastUpdated": "2026-07-20", "originalModel": "DeepSeek V3.1"
|
|
43
|
+
},
|
|
44
|
+
"DeepSeek-V3.2": {
|
|
45
|
+
"codingIndex": 70.5, "mathIndex": 75.0, "agenticIndex": 62.0, "reasoningIndex": 72.0,
|
|
46
|
+
"mmluPro": 78.0, "gpqa": 54.5, "hle": 9.5, "contextWindow": 32000,
|
|
47
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
48
|
+
"lastUpdated": "2026-07-20", "originalModel": "DeepSeek V3.2"
|
|
49
|
+
},
|
|
50
|
+
"deepseek/deepseek-chat": {
|
|
51
|
+
"codingIndex": 65.0, "mathIndex": 70.0, "agenticIndex": 58.0, "reasoningIndex": 68.0,
|
|
52
|
+
"mmluPro": 75.0, "gpqa": 52.0, "hle": 8.4, "contextWindow": 128000,
|
|
53
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
54
|
+
"lastUpdated": "2026-07-20", "originalModel": "DeepSeek Chat"
|
|
55
|
+
},
|
|
56
|
+
"z-ai/glm-5.2": {
|
|
57
|
+
"codingIndex": 82.4, "mathIndex": 79.0, "agenticIndex": 76.1, "reasoningIndex": 78.9,
|
|
58
|
+
"mmluPro": 84.2, "gpqa": 61.8, "hle": 13.5, "contextWindow": 128000,
|
|
59
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
60
|
+
"lastUpdated": "2026-07-20", "originalModel": "GLM 5.2"
|
|
61
|
+
},
|
|
62
|
+
"zai-glm-4.7": {
|
|
63
|
+
"codingIndex": 75.0, "mathIndex": 73.5, "agenticIndex": 68.4, "reasoningIndex": 72.0,
|
|
64
|
+
"mmluPro": 78.5, "gpqa": 55.2, "hle": 10.8, "contextWindow": 128000,
|
|
65
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
66
|
+
"lastUpdated": "2026-07-20", "originalModel": "GLM 4.7"
|
|
67
|
+
},
|
|
68
|
+
"@cf/zai-org/glm-4.7-flash": {
|
|
69
|
+
"codingIndex": 70.0, "mathIndex": 69.0, "agenticIndex": 62.0, "reasoningIndex": 66.0,
|
|
70
|
+
"mmluPro": 73.0, "gpqa": 50.0, "hle": 9.0, "contextWindow": 128000,
|
|
71
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
72
|
+
"lastUpdated": "2026-07-20", "originalModel": "GLM 4.7 Flash"
|
|
73
|
+
},
|
|
74
|
+
"moonshotai/kimi-k2.6": {
|
|
75
|
+
"codingIndex": 79.5, "mathIndex": 77.0, "agenticIndex": 73.2, "reasoningIndex": 76.4,
|
|
76
|
+
"mmluPro": 82.0, "gpqa": 59.0, "hle": 12.4, "contextWindow": 262000,
|
|
77
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
78
|
+
"lastUpdated": "2026-07-20", "originalModel": "Kimi K2.6"
|
|
79
|
+
},
|
|
80
|
+
"@cf/moonshotai/kimi-k2.6": {
|
|
81
|
+
"codingIndex": 79.5, "mathIndex": 77.0, "agenticIndex": 73.2, "reasoningIndex": 76.4,
|
|
82
|
+
"mmluPro": 82.0, "gpqa": 59.0, "hle": 12.4, "contextWindow": 262000,
|
|
83
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
84
|
+
"lastUpdated": "2026-07-20", "originalModel": "Kimi K2.6"
|
|
85
|
+
},
|
|
86
|
+
"@cf/moonshotai/kimi-k2.7-code": {
|
|
87
|
+
"codingIndex": 81.0, "mathIndex": 76.5, "agenticIndex": 74.0, "reasoningIndex": 75.5,
|
|
88
|
+
"mmluPro": 81.5, "gpqa": 58.0, "hle": 12.0, "contextWindow": 262000,
|
|
89
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
90
|
+
"lastUpdated": "2026-07-20", "originalModel": "Kimi K2.7 Code"
|
|
91
|
+
},
|
|
92
|
+
"minimaxai/minimax-m2.7": {
|
|
93
|
+
"codingIndex": 77.5, "mathIndex": 75.0, "agenticIndex": 70.0, "reasoningIndex": 74.5,
|
|
94
|
+
"mmluPro": 80.5, "gpqa": 56.0, "hle": 11.5, "contextWindow": 200000,
|
|
95
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
96
|
+
"lastUpdated": "2026-07-20", "originalModel": "MiniMax M2.7"
|
|
97
|
+
},
|
|
98
|
+
"minimaxai/minimax-m3": {
|
|
99
|
+
"codingIndex": 78.0, "mathIndex": 76.0, "agenticIndex": 71.0, "reasoningIndex": 75.0,
|
|
100
|
+
"mmluPro": 81.0, "gpqa": 57.0, "hle": 12.0, "contextWindow": 1000000,
|
|
101
|
+
"supportsReasoning": true, "supportsVision": true,
|
|
102
|
+
"lastUpdated": "2026-07-20", "originalModel": "MiniMax M3"
|
|
103
|
+
},
|
|
104
|
+
"MiniMax-M2.7": {
|
|
105
|
+
"codingIndex": 77.5, "mathIndex": 75.0, "agenticIndex": 70.0, "reasoningIndex": 74.5,
|
|
106
|
+
"mmluPro": 80.5, "gpqa": 56.0, "hle": 11.5, "contextWindow": 192000,
|
|
107
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
108
|
+
"lastUpdated": "2026-07-20", "originalModel": "MiniMax M2.7"
|
|
109
|
+
},
|
|
110
|
+
"stepfun-ai/step-3.7-flash": {
|
|
111
|
+
"codingIndex": 73.5, "mathIndex": 74.0, "agenticIndex": 68.0, "reasoningIndex": 72.0,
|
|
112
|
+
"mmluPro": 78.0, "gpqa": 53.0, "hle": 10.5, "contextWindow": 256000,
|
|
113
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
114
|
+
"lastUpdated": "2026-07-20", "originalModel": "Step 3.7 Flash"
|
|
115
|
+
},
|
|
116
|
+
"openai/gpt-oss-120b": {
|
|
117
|
+
"codingIndex": 62.0, "mathIndex": 64.0, "agenticIndex": 58.0, "reasoningIndex": 63.0,
|
|
118
|
+
"mmluPro": 70.0, "gpqa": 52.0, "hle": 9.0, "contextWindow": 128000,
|
|
119
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
120
|
+
"lastUpdated": "2026-07-20", "originalModel": "GPT OSS 120B"
|
|
121
|
+
},
|
|
122
|
+
"gpt-oss-120b": {
|
|
123
|
+
"codingIndex": 62.0, "mathIndex": 64.0, "agenticIndex": 58.0, "reasoningIndex": 63.0,
|
|
124
|
+
"mmluPro": 70.0, "gpqa": 52.0, "hle": 9.0, "contextWindow": 128000,
|
|
125
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
126
|
+
"lastUpdated": "2026-07-20", "originalModel": "GPT OSS 120B"
|
|
127
|
+
},
|
|
128
|
+
"openai/gpt-oss-20b": {
|
|
129
|
+
"codingIndex": 50.0, "mathIndex": 52.0, "agenticIndex": 46.0, "reasoningIndex": 51.0,
|
|
130
|
+
"mmluPro": 58.0, "gpqa": 42.0, "hle": 6.5, "contextWindow": 128000,
|
|
131
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
132
|
+
"lastUpdated": "2026-07-20", "originalModel": "GPT OSS 20B"
|
|
133
|
+
},
|
|
134
|
+
"gpt-oss-20b": {
|
|
135
|
+
"codingIndex": 50.0, "mathIndex": 52.0, "agenticIndex": 46.0, "reasoningIndex": 51.0,
|
|
136
|
+
"mmluPro": 58.0, "gpqa": 42.0, "hle": 6.5, "contextWindow": 128000,
|
|
137
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
138
|
+
"lastUpdated": "2026-07-20", "originalModel": "GPT OSS 20B"
|
|
139
|
+
},
|
|
140
|
+
"meta/llama-4-maverick-17b-128e-instruct": {
|
|
141
|
+
"codingIndex": 73.5, "mathIndex": 70.0, "agenticIndex": 65.0, "reasoningIndex": 71.0,
|
|
142
|
+
"mmluPro": 78.0, "gpqa": 53.0, "hle": 10.0, "contextWindow": 1000000,
|
|
143
|
+
"supportsReasoning": false, "supportsVision": true,
|
|
144
|
+
"lastUpdated": "2026-07-20", "originalModel": "Llama 4 Maverick"
|
|
145
|
+
},
|
|
146
|
+
"meta-llama/llama-4-scout-17b-16e-instruct": {
|
|
147
|
+
"codingIndex": 28.0, "mathIndex": 25.0, "agenticIndex": 22.0, "reasoningIndex": 26.0,
|
|
148
|
+
"mmluPro": 30.0, "gpqa": 18.0, "hle": 2.0, "contextWindow": 10000000,
|
|
149
|
+
"supportsReasoning": false, "supportsVision": true,
|
|
150
|
+
"lastUpdated": "2026-07-20", "originalModel": "Llama 4 Scout"
|
|
151
|
+
},
|
|
152
|
+
"@cf/meta/llama-4-scout-17b-16e-instruct": {
|
|
153
|
+
"codingIndex": 28.0, "mathIndex": 25.0, "agenticIndex": 22.0, "reasoningIndex": 26.0,
|
|
154
|
+
"mmluPro": 30.0, "gpqa": 18.0, "hle": 2.0, "contextWindow": 10000000,
|
|
155
|
+
"supportsReasoning": false, "supportsVision": true,
|
|
156
|
+
"lastUpdated": "2026-07-20", "originalModel": "Llama 4 Scout"
|
|
157
|
+
},
|
|
158
|
+
"meta/llama-3.3-70b-versatile": {
|
|
159
|
+
"codingIndex": 22.0, "mathIndex": 24.0, "agenticIndex": 18.0, "reasoningIndex": 23.0,
|
|
160
|
+
"mmluPro": 28.0, "gpqa": 16.0, "hle": 1.5, "contextWindow": 131072,
|
|
161
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
162
|
+
"lastUpdated": "2026-07-20", "originalModel": "Llama 3.3 70B Versatile"
|
|
163
|
+
},
|
|
164
|
+
"llama-3.3-70b-versatile": {
|
|
165
|
+
"codingIndex": 22.0, "mathIndex": 24.0, "agenticIndex": 18.0, "reasoningIndex": 23.0,
|
|
166
|
+
"mmluPro": 28.0, "gpqa": 16.0, "hle": 1.5, "contextWindow": 131072,
|
|
167
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
168
|
+
"lastUpdated": "2026-07-20", "originalModel": "Llama 3.3 70B Versatile"
|
|
169
|
+
},
|
|
170
|
+
"Meta-Llama-3.3-70B-Instruct": {
|
|
171
|
+
"codingIndex": 22.0, "mathIndex": 24.0, "agenticIndex": 18.0, "reasoningIndex": 23.0,
|
|
172
|
+
"mmluPro": 28.0, "gpqa": 16.0, "hle": 1.5, "contextWindow": 128000,
|
|
173
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
174
|
+
"lastUpdated": "2026-07-20", "originalModel": "Llama 3.3 70B Instruct"
|
|
175
|
+
},
|
|
176
|
+
"llama-3.1-8b-instant": {
|
|
177
|
+
"codingIndex": 18.0, "mathIndex": 19.0, "agenticIndex": 14.0, "reasoningIndex": 17.0,
|
|
178
|
+
"mmluPro": 22.0, "gpqa": 12.0, "hle": 1.0, "contextWindow": 131072,
|
|
179
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
180
|
+
"lastUpdated": "2026-07-20", "originalModel": "Llama 3.1 8B Instant"
|
|
181
|
+
},
|
|
182
|
+
"qwen/qwen3.6-27b": {
|
|
183
|
+
"codingIndex": 76.5, "mathIndex": 74.0, "agenticIndex": 70.0, "reasoningIndex": 73.0,
|
|
184
|
+
"mmluPro": 79.0, "gpqa": 55.0, "hle": 11.0, "contextWindow": 131072,
|
|
185
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
186
|
+
"lastUpdated": "2026-07-20", "originalModel": "Qwen3.6 27B"
|
|
187
|
+
},
|
|
188
|
+
"qwen/qwen2.5-coder-32b-instruct": {
|
|
189
|
+
"codingIndex": 48.0, "mathIndex": 45.0, "agenticIndex": 42.0, "reasoningIndex": 44.0,
|
|
190
|
+
"mmluPro": 52.0, "gpqa": 32.0, "hle": 4.0, "contextWindow": 128000,
|
|
191
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
192
|
+
"lastUpdated": "2026-07-20", "originalModel": "Qwen2.5 Coder 32B"
|
|
193
|
+
},
|
|
194
|
+
"qwen/qwen3-30b-a3b-fp8": {
|
|
195
|
+
"codingIndex": 65.0, "mathIndex": 64.0, "agenticIndex": 58.0, "reasoningIndex": 63.0,
|
|
196
|
+
"mmluPro": 70.0, "gpqa": 48.0, "hle": 8.0, "contextWindow": 131072,
|
|
197
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
198
|
+
"lastUpdated": "2026-07-20", "originalModel": "Qwen3 30B A3B"
|
|
199
|
+
},
|
|
200
|
+
"mistralai/mistral-medium-3.5-128b": {
|
|
201
|
+
"codingIndex": 76.5, "mathIndex": 74.0, "agenticIndex": 70.5, "reasoningIndex": 73.0,
|
|
202
|
+
"mmluPro": 79.0, "gpqa": 56.0, "hle": 11.2, "contextWindow": 256000,
|
|
203
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
204
|
+
"lastUpdated": "2026-07-20", "originalModel": "Mistral Medium 3.5"
|
|
205
|
+
},
|
|
206
|
+
"mistralai/mistral-small-4-119b-2603": {
|
|
207
|
+
"codingIndex": 60.0, "mathIndex": 58.0, "agenticIndex": 55.0, "reasoningIndex": 57.0,
|
|
208
|
+
"mmluPro": 65.0, "gpqa": 44.0, "hle": 7.0, "contextWindow": 256000,
|
|
209
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
210
|
+
"lastUpdated": "2026-07-20", "originalModel": "Mistral Small 4"
|
|
211
|
+
},
|
|
212
|
+
"mistralai/mistral-large-3-675b-instruct-2512": {
|
|
213
|
+
"codingIndex": 58.0, "mathIndex": 56.0, "agenticIndex": 52.0, "reasoningIndex": 55.0,
|
|
214
|
+
"mmluPro": 63.0, "gpqa": 42.0, "hle": 6.5, "contextWindow": 256000,
|
|
215
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
216
|
+
"lastUpdated": "2026-07-20", "originalModel": "Mistral Large 675B"
|
|
217
|
+
},
|
|
218
|
+
"mistralai/ministral-14b-instruct-2512": {
|
|
219
|
+
"codingIndex": 34.0, "mathIndex": 32.0, "agenticIndex": 28.0, "reasoningIndex": 31.0,
|
|
220
|
+
"mmluPro": 38.0, "gpqa": 22.0, "hle": 3.0, "contextWindow": 32000,
|
|
221
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
222
|
+
"lastUpdated": "2026-07-20", "originalModel": "Ministral 14B"
|
|
223
|
+
},
|
|
224
|
+
"google/gemma-4-31b-it": {
|
|
225
|
+
"codingIndex": 52.0, "mathIndex": 50.0, "agenticIndex": 46.0, "reasoningIndex": 49.0,
|
|
226
|
+
"mmluPro": 58.0, "gpqa": 38.0, "hle": 5.5, "contextWindow": 256000,
|
|
227
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
228
|
+
"lastUpdated": "2026-07-20", "originalModel": "Gemma 4 31B"
|
|
229
|
+
},
|
|
230
|
+
"gemma-4-31b": {
|
|
231
|
+
"codingIndex": 52.0, "mathIndex": 50.0, "agenticIndex": 46.0, "reasoningIndex": 49.0,
|
|
232
|
+
"mmluPro": 58.0, "gpqa": 38.0, "hle": 5.5, "contextWindow": 128000,
|
|
233
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
234
|
+
"lastUpdated": "2026-07-20", "originalModel": "Gemma 4 31B"
|
|
235
|
+
},
|
|
236
|
+
"@cf/google/gemma-4-26b-a4b-it": {
|
|
237
|
+
"codingIndex": 48.0, "mathIndex": 46.0, "agenticIndex": 42.0, "reasoningIndex": 45.0,
|
|
238
|
+
"mmluPro": 54.0, "gpqa": 35.0, "hle": 5.0, "contextWindow": 128000,
|
|
239
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
240
|
+
"lastUpdated": "2026-07-20", "originalModel": "Gemma 4 26B"
|
|
241
|
+
},
|
|
242
|
+
"nvidia/nemotron-3-ultra-550b-a55b": {
|
|
243
|
+
"codingIndex": 71.0, "mathIndex": 70.0, "agenticIndex": 65.0, "reasoningIndex": 69.0,
|
|
244
|
+
"mmluPro": 75.0, "gpqa": 52.0, "hle": 9.5, "contextWindow": 1000000,
|
|
245
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
246
|
+
"lastUpdated": "2026-07-20", "originalModel": "Nemotron 3 Ultra"
|
|
247
|
+
},
|
|
248
|
+
"nvidia/nemotron-3-super-120b-a12b": {
|
|
249
|
+
"codingIndex": 60.0, "mathIndex": 59.0, "agenticIndex": 54.0, "reasoningIndex": 58.0,
|
|
250
|
+
"mmluPro": 65.0, "gpqa": 44.0, "hle": 7.0, "contextWindow": 128000,
|
|
251
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
252
|
+
"lastUpdated": "2026-07-20", "originalModel": "Nemotron 3 Super"
|
|
253
|
+
},
|
|
254
|
+
"nvidia/nemotron-3-nano-30b-a3b": {
|
|
255
|
+
"codingIndex": 38.0, "mathIndex": 36.0, "agenticIndex": 32.0, "reasoningIndex": 35.0,
|
|
256
|
+
"mmluPro": 42.0, "gpqa": 26.0, "hle": 3.5, "contextWindow": 1000000,
|
|
257
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
258
|
+
"lastUpdated": "2026-07-20", "originalModel": "Nemotron 3 Nano"
|
|
259
|
+
},
|
|
260
|
+
"bytedance/seed-oss-36b-instruct": {
|
|
261
|
+
"codingIndex": 56.0, "mathIndex": 54.0, "agenticIndex": 50.0, "reasoningIndex": 53.0,
|
|
262
|
+
"mmluPro": 60.0, "gpqa": 40.0, "hle": 6.0, "contextWindow": 32000,
|
|
263
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
264
|
+
"lastUpdated": "2026-07-20", "originalModel": "Seed OSS 36B"
|
|
265
|
+
},
|
|
266
|
+
"stockmark/stockmark-2-100b-instruct": {
|
|
267
|
+
"codingIndex": 36.0, "mathIndex": 34.0, "agenticIndex": 30.0, "reasoningIndex": 33.0,
|
|
268
|
+
"mmluPro": 40.0, "gpqa": 24.0, "hle": 3.0, "contextWindow": 32000,
|
|
269
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
270
|
+
"lastUpdated": "2026-07-20", "originalModel": "Stockmark 100B"
|
|
271
|
+
},
|
|
272
|
+
"codestral-latest": {
|
|
273
|
+
"codingIndex": 42.0, "mathIndex": 40.0, "agenticIndex": 38.0, "reasoningIndex": 39.0,
|
|
274
|
+
"mmluPro": 48.0, "gpqa": 30.0, "hle": 4.0, "contextWindow": 32000,
|
|
275
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
276
|
+
"lastUpdated": "2026-07-20", "originalModel": "Codestral Latest"
|
|
277
|
+
},
|
|
278
|
+
"qwen/qwq-32b": {
|
|
279
|
+
"codingIndex": 58.0, "mathIndex": 82.0, "agenticIndex": 50.0, "reasoningIndex": 76.0,
|
|
280
|
+
"mmluPro": 75.0, "gpqa": 64.0, "hle": 11.0, "contextWindow": 131072,
|
|
281
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
282
|
+
"lastUpdated": "2026-07-20", "originalModel": "QwQ 32B"
|
|
283
|
+
},
|
|
284
|
+
"poolside/laguna-m.1:free": {
|
|
285
|
+
"codingIndex": 72.0, "mathIndex": 68.0, "agenticIndex": 65.0, "reasoningIndex": 69.0,
|
|
286
|
+
"mmluPro": 74.0, "gpqa": 50.0, "hle": 9.5, "contextWindow": 262000,
|
|
287
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
288
|
+
"lastUpdated": "2026-07-20", "originalModel": "Poolside Laguna M.1"
|
|
289
|
+
},
|
|
290
|
+
"poolside/laguna-xs.2:free": {
|
|
291
|
+
"codingIndex": 68.0, "mathIndex": 65.0, "agenticIndex": 62.0, "reasoningIndex": 65.0,
|
|
292
|
+
"mmluPro": 70.0, "gpqa": 47.0, "hle": 8.5, "contextWindow": 262000,
|
|
293
|
+
"supportsReasoning": false, "supportsVision": false,
|
|
294
|
+
"lastUpdated": "2026-07-20", "originalModel": "Poolside Laguna XS.2"
|
|
295
|
+
},
|
|
296
|
+
"@cf/qwen/qwen3-30b-a3b-fp8": {
|
|
297
|
+
"codingIndex": 65.0, "mathIndex": 64.0, "agenticIndex": 58.0, "reasoningIndex": 63.0,
|
|
298
|
+
"mmluPro": 70.0, "gpqa": 48.0, "hle": 8.0, "contextWindow": 131072,
|
|
299
|
+
"supportsReasoning": true, "supportsVision": false,
|
|
300
|
+
"lastUpdated": "2026-07-20", "originalModel": "Qwen3 30B A3B"
|
|
301
|
+
}
|
|
302
|
+
}
|
package/src/tui/app.js
CHANGED
|
@@ -149,6 +149,69 @@ const mergedModels = buildMergedModels(MODELS)
|
|
|
149
149
|
const mergedModelByLabel = new Map(mergedModels.map(m => [m.label, m]))
|
|
150
150
|
setOpenCodeModelData(mergedModels, mergedModelByLabel)
|
|
151
151
|
|
|
152
|
+
// ๐ Enrichment (t4 + t5): module-level state. The sync part (extended
|
|
153
|
+
// ๐ benchmark catalog stats) is computed lazily on first read via the
|
|
154
|
+
// ๐ getter, so we don't block module load. The async part (models.dev
|
|
155
|
+
// ๐ fetch) runs inside runApp as a background task โ never at module load,
|
|
156
|
+
// ๐ never blocking the TUI from rendering.
|
|
157
|
+
// ๐
|
|
158
|
+
// ๐ The TUI reads from this object on every render to update the footer chips.
|
|
159
|
+
const moduleEnrichmentStats = {
|
|
160
|
+
bench: { total: 0, lastUpdated: 'unknown', source: 'unknown' },
|
|
161
|
+
modelsDev: { 'sources.js': 0, 'models.dev': 0, cached: false },
|
|
162
|
+
}
|
|
163
|
+
let _benchStatsLoaded = false
|
|
164
|
+
function ensureBenchStatsLoaded() {
|
|
165
|
+
if (_benchStatsLoaded) return
|
|
166
|
+
_benchStatsLoaded = true
|
|
167
|
+
try {
|
|
168
|
+
// ๐ require() works synchronously and is safe at module load because
|
|
169
|
+
// ๐ model-merger.js has no top-level await side effects.
|
|
170
|
+
const { getEnrichmentStats } = require('../core/model-merger.js')
|
|
171
|
+
moduleEnrichmentStats.bench = getEnrichmentStats().extendedBench
|
|
172
|
+
} catch (err) {
|
|
173
|
+
if (process.env.FCM_BENCH_DEBUG) console.warn('[t4] enrichment stats failed:', err?.message ?? err)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ๐ Background enrichment: fetch models.dev and update moduleEnrichmentStats
|
|
178
|
+
// ๐ when it resolves. Fully decoupled from runApp โ even if the fetch hangs
|
|
179
|
+
// ๐ for 30s+, the TUI keeps rendering. The chip is updated by the next render
|
|
180
|
+
// ๐ after resolution.
|
|
181
|
+
function runModelsDevEnrichmentInBackground(merged) {
|
|
182
|
+
// ๐ Fire-and-forget; never awaited. If it throws, the catch swallows it.
|
|
183
|
+
;(async () => {
|
|
184
|
+
try {
|
|
185
|
+
// ๐ Bound the total wait to 12s (worst case 3ร4s retries). If the
|
|
186
|
+
// ๐ network is truly down, the chip stays at "0 live" and the TUI
|
|
187
|
+
// ๐ is unaffected. Callers can still trigger a refresh via the
|
|
188
|
+
// ๐ settings panel (future work).
|
|
189
|
+
const timeout = new Promise(resolve => setTimeout(() => resolve(null), 12_000))
|
|
190
|
+
const { overlayModelsDevMetadata } = await import('../core/model-merger.js')
|
|
191
|
+
const result = await Promise.race([
|
|
192
|
+
overlayModelsDevMetadata(merged, { mutate: true }),
|
|
193
|
+
timeout,
|
|
194
|
+
])
|
|
195
|
+
if (!result) {
|
|
196
|
+
if (process.env.FCM_BENCH_DEBUG) console.warn('[t5] models.dev fetch timed out (12s)')
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
let live = 0, curated = 0
|
|
200
|
+
for (const m of result) {
|
|
201
|
+
if (m.metaSource === 'models.dev') live++
|
|
202
|
+
else if (m.metaSource === 'sources.js') curated++
|
|
203
|
+
}
|
|
204
|
+
moduleEnrichmentStats.modelsDev = { 'sources.js': curated, 'models.dev': live, cached: true }
|
|
205
|
+
// ๐ Note: state is owned by runApp โ we don't have a direct ref here.
|
|
206
|
+
// ๐ The footer reads moduleEnrichmentStats lazily on each render, so
|
|
207
|
+
// ๐ the next render will pick up the new counts. We do NOT trigger a
|
|
208
|
+
// ๐ render from here (we're not in the render context).
|
|
209
|
+
} catch (err) {
|
|
210
|
+
if (process.env.FCM_BENCH_DEBUG) console.warn('[t5] models.dev overlay failed:', err?.message ?? err)
|
|
211
|
+
}
|
|
212
|
+
})()
|
|
213
|
+
}
|
|
214
|
+
|
|
152
215
|
// ๐ Provider quota cache is managed by lib/provider-quota-fetchers.js (TTL + backoff).
|
|
153
216
|
// ๐ Usage placeholder logic uses isKnownQuotaTelemetry() from lib/quota-capabilities.js.
|
|
154
217
|
|
|
@@ -189,6 +252,16 @@ const LOCAL_VERSION = pkg.version
|
|
|
189
252
|
// ๐ OpenCode helpers are imported from ../src/opencode.js
|
|
190
253
|
|
|
191
254
|
export async function runApp(cliArgs, config, startupOptions = {}) {
|
|
255
|
+
// ๐ t4: prime the sync extended-benchmark stats so the footer chip is
|
|
256
|
+
// ๐ accurate on the first render (no async, no network โ just a sync read).
|
|
257
|
+
ensureBenchStatsLoaded()
|
|
258
|
+
|
|
259
|
+
// ๐ t5: kick off the async models.dev enrichment in the background. This
|
|
260
|
+
// ๐ does NOT block runApp โ the TUI starts rendering immediately with
|
|
261
|
+
// ๐ curated values, then re-renders when the models.dev fetch resolves.
|
|
262
|
+
// ๐ If the network is unreachable, the chip just stays at "0 live" forever
|
|
263
|
+
// ๐ (no user-visible freeze). The background task is bounded to 12s.
|
|
264
|
+
runModelsDevEnrichmentInBackground(mergedModels)
|
|
192
265
|
|
|
193
266
|
// ๐ Detect user active terminal theme
|
|
194
267
|
detectActiveTheme(config.settings?.theme || 'auto')
|
|
@@ -505,8 +578,27 @@ export async function runApp(cliArgs, config, startupOptions = {}) {
|
|
|
505
578
|
}
|
|
506
579
|
state.probeCacheHits = probeCacheHits
|
|
507
580
|
state.probeCacheMisses = probeCacheMisses
|
|
581
|
+
// ๐ Enrichment (t4 + t5): pulled fresh on every render from moduleEnrichmentStats
|
|
582
|
+
// ๐ (see the tableOpts construction below). No need to mirror into state here.
|
|
508
583
|
state.probeCacheBrokenHidden = state.results.filter(r => r.cachedBroken && r.hidden).length
|
|
509
584
|
|
|
585
|
+
// ๐ Runtime telemetry (t3): load the per-model metrics file + compute the
|
|
586
|
+
// ๐ real-world score for each result so the table can sort/display it.
|
|
587
|
+
// ๐ The file may not exist yet (no daemon traffic) โ that's fine, every
|
|
588
|
+
// ๐ r.realWorldScore stays null and we fall back to SWE-bench.
|
|
589
|
+
try {
|
|
590
|
+
const { loadRuntimeTelemetry, getRealWorldScore } = await import('../core/runtime-telemetry.js')
|
|
591
|
+
loadRuntimeTelemetry() // ๐ populate module-level cache
|
|
592
|
+
for (const r of state.results) {
|
|
593
|
+
const score = getRealWorldScore(r.providerKey, r.modelId)
|
|
594
|
+
r.realWorldScore = score // null when below MIN_CALLS_FOR_SCORE
|
|
595
|
+
}
|
|
596
|
+
state.runtimeTelemetryLoaded = true
|
|
597
|
+
} catch (err) {
|
|
598
|
+
state.runtimeTelemetryLoaded = false
|
|
599
|
+
state.runtimeTelemetryError = err?.message || String(err)
|
|
600
|
+
}
|
|
601
|
+
|
|
510
602
|
// ๐ Define pingModel before JSON mode so `--json` can reuse the same provider-aware
|
|
511
603
|
// ๐ ping path as the interactive TUI without waiting for the PTY/render loop setup.
|
|
512
604
|
pingModel = async (r) => {
|
|
@@ -954,6 +1046,17 @@ export async function runApp(cliArgs, config, startupOptions = {}) {
|
|
|
954
1046
|
probeCacheMisses: state.probeCacheMisses || 0,
|
|
955
1047
|
probeCacheBrokenHidden: state.probeCacheBrokenHidden || 0,
|
|
956
1048
|
showBrokenMode: !!state.showBrokenMode,
|
|
1049
|
+
// ๐ Enrichment chips (t4 + t5): benchmark catalog + models.dev provenance
|
|
1050
|
+
// ๐ Read fresh from moduleEnrichmentStats on every render so the async
|
|
1051
|
+
// ๐ models.dev fetch (background, never blocks the TUI) is reflected as
|
|
1052
|
+
// ๐ soon as it resolves โ even if the user isn't pressing keys.
|
|
1053
|
+
enrichmentBenchCount: moduleEnrichmentStats.bench.total || 0,
|
|
1054
|
+
enrichmentBenchLastUpdated: moduleEnrichmentStats.bench.lastUpdated || null,
|
|
1055
|
+
metaSourceCounts: {
|
|
1056
|
+
'sources.js': moduleEnrichmentStats.modelsDev['sources.js'] || 0,
|
|
1057
|
+
'models.dev': moduleEnrichmentStats.modelsDev['models.dev'] || 0,
|
|
1058
|
+
},
|
|
1059
|
+
modelsDevCacheCached: moduleEnrichmentStats.modelsDev.cached === true,
|
|
957
1060
|
// ๐ Passive quota (t2): live snapshots from response headers, populated
|
|
958
1061
|
// ๐ by pings (every ping pre-warms quota for its provider). See
|
|
959
1062
|
// ๐ src/core/provider-quota-fetchers.js for getAllPassiveQuotas().
|
package/src/tui/cli-help.js
CHANGED
|
@@ -36,6 +36,8 @@ const ANALYSIS_FLAGS = [
|
|
|
36
36
|
{ flag: '--reprobe, --no-cache', description: 'Force-rebuild the persistent probe-cache this run (skip cached healthy models)' },
|
|
37
37
|
{ flag: '--probe-ttl <ms>', description: 'Override probe-cache TTL (default 24h); healthy models within TTL are not re-pinged' },
|
|
38
38
|
{ flag: '--show-broken', description: "Don't auto-hide models that the probe-cache marked broken (one-shot override)" },
|
|
39
|
+
{ flag: '--check-drift', description: 'Diff sources.js against models.dev and print a drift report; exit 1 on mismatch (t5)' },
|
|
40
|
+
{ flag: '--drift-threshold <N>', description: 'Only fail --check-drift when N+ mismatches are found (default: 0 = any drift)' },
|
|
39
41
|
]
|
|
40
42
|
|
|
41
43
|
const CONFIG_FLAGS = [
|
package/src/tui/key-handler.js
CHANGED
|
@@ -836,6 +836,40 @@ export function createKeyHandler(ctx) {
|
|
|
836
836
|
state.tokenUsageError = null
|
|
837
837
|
}
|
|
838
838
|
|
|
839
|
+
// ๐ Runtime Report overlay (t3): per-model real-world breakdown + recent calls.
|
|
840
|
+
// ๐ Reads the local ~/.free-coding-models/runtime-telemetry.json file directly
|
|
841
|
+
// ๐ (the daemon writes to the same file; the CLI doesn't need to talk to it).
|
|
842
|
+
async function openRuntimeReportOverlay() {
|
|
843
|
+
state.runtimeReportOpen = true
|
|
844
|
+
state.runtimeReportScrollOffset = 0
|
|
845
|
+
state.runtimeReportError = null
|
|
846
|
+
state.runtimeReportData = null
|
|
847
|
+
state.runtimeReportSelectedKey = null
|
|
848
|
+
try {
|
|
849
|
+
const { loadRuntimeTelemetry, getAllModelTelemetry } = await import('../core/runtime-telemetry.js')
|
|
850
|
+
const cache = loadRuntimeTelemetry()
|
|
851
|
+
const all = getAllModelTelemetry({ cache })
|
|
852
|
+
const entries = Object.entries(all).sort((a, b) => (b[1].totalCalls || 0) - (a[1].totalCalls || 0))
|
|
853
|
+
state.runtimeReportData = entries
|
|
854
|
+
// ๐ Pre-select the currently-focused model if it has telemetry.
|
|
855
|
+
const focused = state.visibleSorted?.[state.cursor]
|
|
856
|
+
if (focused) {
|
|
857
|
+
const key = `${focused.providerKey}/${focused.modelId}`
|
|
858
|
+
if (entries.find(([k]) => k === key)) state.runtimeReportSelectedKey = key
|
|
859
|
+
}
|
|
860
|
+
} catch (err) {
|
|
861
|
+
state.runtimeReportError = err?.message || 'Failed to load runtime telemetry'
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
function closeRuntimeReportOverlay() {
|
|
866
|
+
state.runtimeReportOpen = false
|
|
867
|
+
state.runtimeReportScrollOffset = 0
|
|
868
|
+
state.runtimeReportError = null
|
|
869
|
+
state.runtimeReportData = null
|
|
870
|
+
state.runtimeReportSelectedKey = null
|
|
871
|
+
}
|
|
872
|
+
|
|
839
873
|
|
|
840
874
|
function cycleToolMode() {
|
|
841
875
|
const modeOrder = getToolModeOrder()
|
|
@@ -1355,6 +1389,7 @@ export function createKeyHandler(ctx) {
|
|
|
1355
1389
|
case 'sort-verdict': return setSortColumnFromCommand('verdict')
|
|
1356
1390
|
case 'sort-stability': return setSortColumnFromCommand('stability')
|
|
1357
1391
|
case 'sort-uptime': return setSortColumnFromCommand('uptime')
|
|
1392
|
+
case 'sort-realworld': return setSortColumnFromCommand('realworld')
|
|
1358
1393
|
case 'open-settings': return openSettingsOverlay()
|
|
1359
1394
|
case 'open-help':
|
|
1360
1395
|
state.helpVisible = true
|
|
@@ -1366,6 +1401,7 @@ export function createKeyHandler(ctx) {
|
|
|
1366
1401
|
case 'open-router-dashboard': return openRouterDashboardOverlay(state)
|
|
1367
1402
|
case 'open-playground': return openPlaygroundOverlay(state)
|
|
1368
1403
|
case 'open-token-usage': return openTokenUsageOverlay()
|
|
1404
|
+
case 'open-runtime-report': return openRuntimeReportOverlay()
|
|
1369
1405
|
case 'open-install-endpoints': return openInstallEndpointsOverlay()
|
|
1370
1406
|
case 'open-installed-models': return openInstalledModelsOverlay()
|
|
1371
1407
|
case 'action-cycle-theme': return cycleGlobalTheme()
|
|
@@ -2120,6 +2156,42 @@ export function createKeyHandler(ctx) {
|
|
|
2120
2156
|
return
|
|
2121
2157
|
}
|
|
2122
2158
|
|
|
2159
|
+
// ๐ Runtime Report overlay (t3): Shift+W. Per-model real-world breakdown +
|
|
2160
|
+
// ๐ recent calls. Scrolling with up/down/pageup/pagedown/escape.
|
|
2161
|
+
if (state.runtimeReportOpen) {
|
|
2162
|
+
if (key.ctrl && key.name === 'c') { exit(0); return }
|
|
2163
|
+
const pageStep = Math.max(1, (state.terminalRows || 1) - 4)
|
|
2164
|
+
if (key.name === 'escape') {
|
|
2165
|
+
closeRuntimeReportOverlay()
|
|
2166
|
+
return
|
|
2167
|
+
}
|
|
2168
|
+
if (key.name === 'up' || key.name === 'k') {
|
|
2169
|
+
state.runtimeReportScrollOffset = Math.max(0, state.runtimeReportScrollOffset - 1)
|
|
2170
|
+
return
|
|
2171
|
+
}
|
|
2172
|
+
if (key.name === 'down' || key.name === 'j') {
|
|
2173
|
+
state.runtimeReportScrollOffset += 1
|
|
2174
|
+
return
|
|
2175
|
+
}
|
|
2176
|
+
if (key.name === 'pageup') {
|
|
2177
|
+
state.runtimeReportScrollOffset = Math.max(0, state.runtimeReportScrollOffset - pageStep)
|
|
2178
|
+
return
|
|
2179
|
+
}
|
|
2180
|
+
if (key.name === 'pagedown') {
|
|
2181
|
+
state.runtimeReportScrollOffset += pageStep
|
|
2182
|
+
return
|
|
2183
|
+
}
|
|
2184
|
+
if (key.name === 'home') {
|
|
2185
|
+
state.runtimeReportScrollOffset = 0
|
|
2186
|
+
return
|
|
2187
|
+
}
|
|
2188
|
+
if (key.name === 'end') {
|
|
2189
|
+
state.runtimeReportScrollOffset = Number.MAX_SAFE_INTEGER
|
|
2190
|
+
return
|
|
2191
|
+
}
|
|
2192
|
+
return
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2123
2195
|
// ๐ Router Onboarding overlay: shown on first launch. Y=yes enable, N=not now, Esc=cancel.
|
|
2124
2196
|
if (state.routerOnboardingOpen) {
|
|
2125
2197
|
if (key.ctrl && key.name === 'c') { exit(0); return }
|
|
@@ -2872,6 +2944,14 @@ export function createKeyHandler(ctx) {
|
|
|
2872
2944
|
return
|
|
2873
2945
|
}
|
|
2874
2946
|
|
|
2947
|
+
// ๐ Shift+W: open the Runtime Report overlay (t3) โ per-model real-world
|
|
2948
|
+
// ๐ success rate + throughput + recent calls. See command palette
|
|
2949
|
+
// ๐ 'open-runtime-report' for the same action.
|
|
2950
|
+
if (key.name === 'w' && key.shift && !key.alt && !key.ctrl && !key.meta) {
|
|
2951
|
+
openRuntimeReportOverlay()
|
|
2952
|
+
return
|
|
2953
|
+
}
|
|
2954
|
+
|
|
2875
2955
|
// ๐ E cycles: Normal โ Configured only โ Usable only โ Normal
|
|
2876
2956
|
// ๐ Configured only: hides models with no key or noauth/auth_error health
|
|
2877
2957
|
// ๐ Usable only: only shows models with Health UP and Verdict โค Slow (Perfect/Normal/Slow)
|
package/src/tui/render-table.js
CHANGED
|
@@ -155,6 +155,13 @@ export const PROVIDER_COLOR = new Proxy({}, {
|
|
|
155
155
|
* probeCacheMisses?: number, // t1: number of models that needed a live probe
|
|
156
156
|
* probeCacheBrokenHidden?: number, // t1: number of broken models auto-hidden this session
|
|
157
157
|
* showBrokenMode?: boolean, // t1: true when Shift+B has un-hidden broken models
|
|
158
|
+
* enrichmentBenchCount?: number, // t4: extended benchmark catalog size (committed JSON)
|
|
159
|
+
* enrichmentBenchLastUpdated?: string, // t4: lastUpdated field from the catalog _meta
|
|
160
|
+
* metaSourceCounts?: { // t5: count of models per metadata source
|
|
161
|
+
* 'sources.js': number,
|
|
162
|
+
* 'models.dev': number,
|
|
163
|
+
* },
|
|
164
|
+
* modelsDevCacheCached?: boolean, // t5: whether the models.dev cache is still within TTL
|
|
158
165
|
* quota?: Record<string, { // t2: live quota from response headers
|
|
159
166
|
* remaining: number, limit: number, percent: number,
|
|
160
167
|
* source: 'header'|'endpoint', lastUpdated: number, windowType?: string,
|
|
@@ -209,6 +216,10 @@ export function renderTable({
|
|
|
209
216
|
probeCacheMisses = 0,
|
|
210
217
|
probeCacheBrokenHidden = 0,
|
|
211
218
|
showBrokenMode = false,
|
|
219
|
+
enrichmentBenchCount = 0,
|
|
220
|
+
enrichmentBenchLastUpdated = null,
|
|
221
|
+
metaSourceCounts = null,
|
|
222
|
+
modelsDevCacheCached = false,
|
|
212
223
|
quota = {},
|
|
213
224
|
} = _) {
|
|
214
225
|
// ๐ Filter out hidden models for display
|
|
@@ -1224,6 +1235,29 @@ export function renderTable({
|
|
|
1224
1235
|
probeCacheLabel = chalk.bgRgb(40, 90, 140).rgb(220, 235, 255).bold(` ${cachedTxt}${brokenTxt} `)
|
|
1225
1236
|
}
|
|
1226
1237
|
|
|
1238
|
+
// ๐ Enrichment chips (t4 + t5):
|
|
1239
|
+
// ๐ `๐ bench N (date) ยท ๐ก live K / ๐ฆ cached M`
|
|
1240
|
+
// ๐ Always shown when any enrichment state exists.
|
|
1241
|
+
let enrichmentLabel = ''
|
|
1242
|
+
if ((enrichmentBenchCount && enrichmentBenchCount > 0) || metaSourceCounts) {
|
|
1243
|
+
const parts = []
|
|
1244
|
+
if (enrichmentBenchCount && enrichmentBenchCount > 0) {
|
|
1245
|
+
const dateTxt = enrichmentBenchLastUpdated && enrichmentBenchLastUpdated !== 'unknown'
|
|
1246
|
+
? ` (${enrichmentBenchLastUpdated})`
|
|
1247
|
+
: ''
|
|
1248
|
+
parts.push(`๐ bench ${enrichmentBenchCount}${dateTxt}`)
|
|
1249
|
+
}
|
|
1250
|
+
if (metaSourceCounts && (metaSourceCounts['models.dev'] > 0 || metaSourceCounts['sources.js'] > 0)) {
|
|
1251
|
+
const liveTxt = metaSourceCounts['models.dev'] ?? 0
|
|
1252
|
+
const cachedTxt = metaSourceCounts['sources.js'] ?? 0
|
|
1253
|
+
const liveIcon = modelsDevCacheCached ? '๐ก' : '๐ฆ'
|
|
1254
|
+
parts.push(`${liveIcon} ${liveTxt} live ยท ${cachedTxt} curated`)
|
|
1255
|
+
}
|
|
1256
|
+
if (parts.length > 0) {
|
|
1257
|
+
enrichmentLabel = chalk.bgRgb(80, 50, 110).rgb(230, 220, 245).bold(` ${parts.join(' ยท ')} `)
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1227
1261
|
// ๐ Passive quota chip (t2): `๐ groq 78% ยท sambanova 41%` (top-N depleted first).
|
|
1228
1262
|
// ๐ Shows live rate-limit headers that the daemon / pings collected from upstream
|
|
1229
1263
|
// ๐ responses. Zero extra network requests โ see provider-quota-fetchers.js.
|
|
@@ -1243,8 +1277,8 @@ export function renderTable({
|
|
|
1243
1277
|
}
|
|
1244
1278
|
}
|
|
1245
1279
|
|
|
1246
|
-
// ๐ Line 3: Speed Test + Global Benchmark + Probe + Probe-cache + Quota + Last release
|
|
1247
|
-
if (releaseLabel || speedTestLabel || globalBenchmarkLabel || probeLabel || probeCacheLabel || quotaLabel) {
|
|
1280
|
+
// ๐ Line 3: Speed Test + Global Benchmark + Probe + Probe-cache + Enrichment + Quota + Last release
|
|
1281
|
+
if (releaseLabel || speedTestLabel || globalBenchmarkLabel || probeLabel || probeCacheLabel || enrichmentLabel || quotaLabel) {
|
|
1248
1282
|
const parts = [
|
|
1249
1283
|
{ text: ' ', key: null },
|
|
1250
1284
|
{ text: speedTestLabel, key: 'a' },
|
|
@@ -1254,6 +1288,8 @@ export function renderTable({
|
|
|
1254
1288
|
{ text: probeLabel, key: null },
|
|
1255
1289
|
{ text: probeCacheLabel ? ' ' : '', key: null },
|
|
1256
1290
|
{ text: probeCacheLabel, key: null },
|
|
1291
|
+
{ text: enrichmentLabel ? ' ' : '', key: null },
|
|
1292
|
+
{ text: enrichmentLabel, key: null },
|
|
1257
1293
|
{ text: quotaLabel ? ' ' : '', key: null },
|
|
1258
1294
|
{ text: quotaLabel, key: null },
|
|
1259
1295
|
{ text: ' ', key: null },
|
package/src/tui/tui-state.js
CHANGED
|
@@ -297,6 +297,15 @@ export function createTuiState({
|
|
|
297
297
|
probeCacheTtlMs: null, // ๐ Set in app.js from cliArgs.probeTtlMs || DEFAULT
|
|
298
298
|
showBrokenMode: false,
|
|
299
299
|
|
|
300
|
+
// ๐ Runtime telemetry overlay state (t3): Shift+W opens the Runtime Report
|
|
301
|
+
// ๐ overlay. Data is loaded fresh from ~/.free-coding-models/runtime-telemetry.json
|
|
302
|
+
// ๐ when the overlay opens โ no polling, no daemon dependency.
|
|
303
|
+
runtimeReportOpen: false,
|
|
304
|
+
runtimeReportScrollOffset: 0,
|
|
305
|
+
runtimeReportError: null,
|
|
306
|
+
runtimeReportData: null, // ๐ Array<[key, ModelTelemetry]>
|
|
307
|
+
runtimeReportSelectedKey: null, // ๐ Pre-selected model key
|
|
308
|
+
|
|
300
309
|
// ๐ Header click flash animation: briefly highlights the clicked column header
|
|
301
310
|
// ๐ with an inverse/bright style for ~250ms (3 frames at 12 FPS).
|
|
302
311
|
headerFlashColumn: null, // ๐ Column name being flashed (null = no flash active)
|