free-coding-models 0.1.20 β 0.1.22
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/bin/free-coding-models.js +39 -44
- package/package.json +1 -1
|
@@ -201,7 +201,7 @@ async function promptModeSelection(latestVersion) {
|
|
|
201
201
|
options.push({
|
|
202
202
|
label: 'Read Changelogs',
|
|
203
203
|
icon: 'π',
|
|
204
|
-
description: 'Open
|
|
204
|
+
description: 'Open local CHANGELOG.md file',
|
|
205
205
|
})
|
|
206
206
|
}
|
|
207
207
|
|
|
@@ -328,10 +328,13 @@ const spinCell = (f, o = 0) => chalk.dim.yellow(FRAMES[(f + o) % FRAMES.length].
|
|
|
328
328
|
|
|
329
329
|
// π renderTable: mode param controls footer hint text (opencode vs openclaw)
|
|
330
330
|
function renderTable(results, pendingPings, frame, cursor = null, sortColumn = 'avg', sortDirection = 'asc', pingInterval = PING_INTERVAL, lastPingTime = Date.now(), mode = 'opencode', tierFilter = null) {
|
|
331
|
-
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
const
|
|
331
|
+
// π Filter out hidden models for display
|
|
332
|
+
const visibleResults = results.filter(r => !r.hidden)
|
|
333
|
+
|
|
334
|
+
const up = visibleResults.filter(r => r.status === 'up').length
|
|
335
|
+
const down = visibleResults.filter(r => r.status === 'down').length
|
|
336
|
+
const timeout = visibleResults.filter(r => r.status === 'timeout').length
|
|
337
|
+
const pending = visibleResults.filter(r => r.status === 'pending').length
|
|
335
338
|
|
|
336
339
|
// π Calculate seconds until next ping
|
|
337
340
|
const timeSinceLastPing = Date.now() - lastPingTime
|
|
@@ -372,7 +375,7 @@ function renderTable(results, pendingPings, frame, cursor = null, sortColumn = '
|
|
|
372
375
|
const W_UPTIME = 6
|
|
373
376
|
|
|
374
377
|
// π Sort models using the shared helper
|
|
375
|
-
const sorted = sortResults(
|
|
378
|
+
const sorted = sortResults(visibleResults, sortColumn, sortDirection)
|
|
376
379
|
|
|
377
380
|
const lines = [
|
|
378
381
|
'',
|
|
@@ -1041,11 +1044,12 @@ async function main() {
|
|
|
1041
1044
|
runUpdate(latestVersion)
|
|
1042
1045
|
}
|
|
1043
1046
|
|
|
1044
|
-
// π Handle "Read Changelogs" selection β open
|
|
1047
|
+
// π Handle "Read Changelogs" selection β open local CHANGELOG.md file
|
|
1045
1048
|
if (mode === 'changelogs') {
|
|
1046
1049
|
const { exec } = await import('child_process')
|
|
1047
|
-
|
|
1048
|
-
|
|
1050
|
+
const changelogPath = join(process.cwd(), 'CHANGELOG.md')
|
|
1051
|
+
exec(`open "${changelogPath}"`)
|
|
1052
|
+
console.log(chalk.dim(' π Opening local changelogs fileβ¦'))
|
|
1049
1053
|
process.exit(0)
|
|
1050
1054
|
}
|
|
1051
1055
|
|
|
@@ -1055,21 +1059,33 @@ async function main() {
|
|
|
1055
1059
|
console.log()
|
|
1056
1060
|
}
|
|
1057
1061
|
|
|
1058
|
-
// π
|
|
1062
|
+
// π Create results array with all models initially visible
|
|
1059
1063
|
let results = MODELS.map(([modelId, label, tier], i) => ({
|
|
1060
1064
|
idx: i + 1, modelId, label, tier,
|
|
1061
1065
|
status: 'pending',
|
|
1062
1066
|
pings: [], // π All ping results (ms or 'TIMEOUT')
|
|
1063
1067
|
httpCode: null,
|
|
1068
|
+
hidden: false, // π Simple flag to hide/show models
|
|
1064
1069
|
}))
|
|
1065
1070
|
|
|
1071
|
+
// π Apply filters by setting hidden flag
|
|
1066
1072
|
if (bestMode) {
|
|
1067
|
-
results
|
|
1073
|
+
results.forEach(r => {
|
|
1074
|
+
r.hidden = !(r.tier === 'S+' || r.tier === 'S' || r.tier === 'A+')
|
|
1075
|
+
})
|
|
1068
1076
|
}
|
|
1069
1077
|
|
|
1070
|
-
// π Apply tier letter filter if --tier X was given
|
|
1078
|
+
// π Apply tier letter filter if --tier X was given (just sets initial state)
|
|
1079
|
+
// π User can still change filter with E/D keys later
|
|
1071
1080
|
if (tierFilter) {
|
|
1072
|
-
|
|
1081
|
+
const tierSet = TIER_LETTER_MAP[tierFilter]
|
|
1082
|
+
if (!tierSet) {
|
|
1083
|
+
console.error(chalk.red(` β Unknown tier "${tierFilter}". Valid tiers: S, A, B, C`))
|
|
1084
|
+
process.exit(1)
|
|
1085
|
+
}
|
|
1086
|
+
results.forEach(r => {
|
|
1087
|
+
r.hidden = !tierSet.includes(r.tier)
|
|
1088
|
+
})
|
|
1073
1089
|
}
|
|
1074
1090
|
|
|
1075
1091
|
// π Add interactive selection state - cursor index and user's choice
|
|
@@ -1105,38 +1121,17 @@ async function main() {
|
|
|
1105
1121
|
process.on('SIGINT', () => exit(0))
|
|
1106
1122
|
process.on('SIGTERM', () => exit(0))
|
|
1107
1123
|
|
|
1108
|
-
// π Apply tier filter
|
|
1109
|
-
// π
|
|
1124
|
+
// π Apply tier filter based on current state.tierFilter
|
|
1125
|
+
// π This preserves all ping history by merging with existing results
|
|
1110
1126
|
function applyTierFilter() {
|
|
1111
|
-
const
|
|
1112
|
-
idx: i + 1, modelId, label, tier,
|
|
1113
|
-
status: 'pending',
|
|
1114
|
-
pings: [],
|
|
1115
|
-
httpCode: null,
|
|
1116
|
-
}))
|
|
1117
|
-
|
|
1118
|
-
if (!state.tierFilter) {
|
|
1119
|
-
return allModels
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
// π Filter models by tier and preserve existing ping history
|
|
1123
|
-
const filteredModels = allModels.filter(model =>
|
|
1124
|
-
TIER_LETTER_MAP[state.tierFilter].includes(model.tier)
|
|
1125
|
-
)
|
|
1127
|
+
const tierSet = state.tierFilter ? TIER_LETTER_MAP[state.tierFilter] : null
|
|
1126
1128
|
|
|
1127
|
-
// π
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
if (existingResult) {
|
|
1131
|
-
return {
|
|
1132
|
-
...model,
|
|
1133
|
-
status: existingResult.status,
|
|
1134
|
-
pings: [...existingResult.pings],
|
|
1135
|
-
httpCode: existingResult.httpCode
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
return model
|
|
1129
|
+
// π Simple approach: just update hidden flag on existing results
|
|
1130
|
+
state.results.forEach(r => {
|
|
1131
|
+
r.hidden = tierSet ? !tierSet.includes(r.tier) : false
|
|
1139
1132
|
})
|
|
1133
|
+
|
|
1134
|
+
return state.results // π Return same array, just updated hidden flags
|
|
1140
1135
|
}
|
|
1141
1136
|
|
|
1142
1137
|
// π Setup keyboard input for interactive selection during pings
|
|
@@ -1294,14 +1289,14 @@ async function main() {
|
|
|
1294
1289
|
}
|
|
1295
1290
|
|
|
1296
1291
|
// π Initial ping of all models
|
|
1297
|
-
const initialPing = Promise.all(results.map(r => pingModel(r)))
|
|
1292
|
+
const initialPing = Promise.all(state.results.map(r => pingModel(r)))
|
|
1298
1293
|
|
|
1299
1294
|
// π Continuous ping loop with dynamic interval (adjustable with W/X keys)
|
|
1300
1295
|
const schedulePing = () => {
|
|
1301
1296
|
state.pingIntervalObj = setTimeout(async () => {
|
|
1302
1297
|
state.lastPingTime = Date.now()
|
|
1303
1298
|
|
|
1304
|
-
results.forEach(r => {
|
|
1299
|
+
state.results.forEach(r => {
|
|
1305
1300
|
pingModel(r).catch(() => {
|
|
1306
1301
|
// Individual ping failures don't crash the loop
|
|
1307
1302
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.22",
|
|
4
4
|
"description": "Find the fastest coding LLM models in seconds β ping free models from multiple providers, pick the best one for OpenCode, Cursor, or any AI coding assistant.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nvidia",
|