free-coding-models 0.5.53 โ 0.5.54
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.
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog v0.5.54 - 2026-07-25
|
|
2
|
+
|
|
3
|
+
### Fixed
|
|
4
|
+
- ๐ ๏ธ **`patch-openclaw.js` now respects real model metadata** ([#133](https://github.com/vava-nessa/free-coding-models/issues/133)) โ the script was destructuring only 3 of 5 fields from each `nvidiaNim` tuple (`[modelId, label, tier, sweScore, ctx]`), so it dropped the real `ctx` and fell back to a hardcoded `contextWindow` per tier (e.g. all S+ models got 128000, even `DeepSeek V4 Flash` which actually has 1M context). Now it parses the real `ctx` string (`'200k'` โ 200000, `'1M'` โ 1_000_000) and persists `tier`, `sweScore`, and a `source` field for traceability.
|
|
5
|
+
|
|
6
|
+
- ๐งญ **fcm_router now shows a real label in the TUI** ([#140](https://github.com/vava-nessa/free-coding-models/issues/140)) โ added a `fcm_router` entry to `PROVIDER_METADATA` so every UI surface (Setup wizard, Settings panel, tool launchers, TUI filters) resolves "Smart Router Daemon" instead of the raw key `fcm_router` (which users were reading as "Unknown"). The local `getProviderLabel()` in `endpoint-installer.js` was the only place that knew about `fcm_router`; it now falls through to `PROVIDER_METADATA` so all callers stay in sync.
|
|
7
|
+
|
|
8
|
+
### Maintenance
|
|
9
|
+
- ๐งน **Closed 3 stale issues that were already fixed** in older releases (verified by `git log` on the relevant code paths):
|
|
10
|
+
- [#116](https://github.com/vava-nessa/free-coding-models/issues/116) โ Docker API 404s (fixed in v0.5.28, commit `2c07925`)
|
|
11
|
+
- [#117](https://github.com/vava-nessa/free-coding-models/issues/117) โ "pending" status confusing (fixed in v0.5.28, same commit)
|
|
12
|
+
- [#118](https://github.com/vava-nessa/free-coding-models/issues/118) โ Probe loop silent stall (fixed in v0.5.36, commit `f0dd3d8`)
|
|
13
|
+
- ๐งช **+18 new unit tests** for `patch-openclaw.js` parseCtx/defaultMaxTokens (11) and `provider-metadata.js` fcm_router lookup (7). All test runs go through `pnpm test` (no extra setup needed).
|
|
14
|
+
|
|
15
|
+
### Pre-flight checks
|
|
16
|
+
- 584/584 tests pass (`pnpm test`)
|
|
17
|
+
- `vite build` succeeds (260 modules, ~283ms)
|
|
18
|
+
- CLI loads cleanly (`free-coding-models --help`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "free-coding-models",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.54",
|
|
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",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
],
|
|
54
54
|
"scripts": {
|
|
55
55
|
"start": "node bin/free-coding-models.js",
|
|
56
|
-
"test": "node --test test/test.js test/fcm-agent-core.test.js",
|
|
56
|
+
"test": "node --test test/test.js test/fcm-agent-core.test.js test/patch-openclaw.test.js test/provider-metadata.test.js",
|
|
57
57
|
"prepack": "npm run build:web",
|
|
58
58
|
"dev": "node scripts/dev-web.mjs",
|
|
59
59
|
"dev:web": "node scripts/dev-web.mjs",
|
package/patch-openclaw.js
CHANGED
|
@@ -18,21 +18,24 @@ const OPENCLAW_JSON = join(homedir(), '.openclaw', 'openclaw.json')
|
|
|
18
18
|
console.log('๐ฆ Patching OpenClaw for full NVIDIA model support...\n')
|
|
19
19
|
|
|
20
20
|
// โโโ Helper functions โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
21
|
+
// ๐ Parse a context-window string from sources.js: "200k" โ 200_000, "1M" โ 1_000_000.
|
|
22
|
+
// Falls back to 8192 if the format is unexpected.
|
|
23
|
+
function parseCtx(ctxStr) {
|
|
24
|
+
if (typeof ctxStr !== 'string') return 8192
|
|
25
|
+
const m = ctxStr.trim().match(/^(\d+(?:\.\d+)?)([kKmM]?)$/)
|
|
26
|
+
if (!m) return 8192
|
|
27
|
+
const n = Number(m[1])
|
|
28
|
+
const unit = m[2]
|
|
29
|
+
if (unit === 'M' || unit === 'm') return Math.round(n * 1_000_000)
|
|
30
|
+
if (unit === 'K' || unit === 'k') return Math.round(n * 1000)
|
|
31
|
+
return Math.round(n)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ๐ Choose a sensible maxTokens from the real contextWindow.
|
|
35
|
+
// Rule: ~5% of context, clamped between 2k and 16k.
|
|
36
|
+
function defaultMaxTokens(ctx) {
|
|
37
|
+
const pct = Math.round(ctx * 0.05)
|
|
38
|
+
return Math.max(2048, Math.min(16384, pct))
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
// โโโ Patch models.json โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -70,22 +73,29 @@ if (!modelsConfig.providers.nvidia) {
|
|
|
70
73
|
const existingModelIds = new Set(modelsConfig.providers.nvidia.models.map(m => m.id))
|
|
71
74
|
|
|
72
75
|
// Add all models from sources.js
|
|
76
|
+
// ๐ Each nvidiaNim tuple is: [modelId, label, tier, sweScore, ctx] โ see sources.js:39
|
|
73
77
|
let addedCount = 0
|
|
74
|
-
for (const [modelId, label, tier] of nvidiaNim) {
|
|
78
|
+
for (const [modelId, label, tier, sweScore, ctx] of nvidiaNim) {
|
|
75
79
|
if (existingModelIds.has(modelId)) {
|
|
76
80
|
continue // Skip already existing models
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
const
|
|
83
|
+
const contextWindow = parseCtx(ctx)
|
|
84
|
+
const maxTokens = defaultMaxTokens(contextWindow)
|
|
80
85
|
const isThinking = modelId.includes('thinking')
|
|
81
86
|
|
|
82
87
|
modelsConfig.providers.nvidia.models.push({
|
|
83
88
|
id: modelId,
|
|
84
89
|
name: label,
|
|
85
|
-
contextWindow
|
|
86
|
-
maxTokens
|
|
90
|
+
contextWindow,
|
|
91
|
+
maxTokens,
|
|
87
92
|
reasoning: isThinking,
|
|
88
93
|
input: ['text'],
|
|
94
|
+
// ๐ OpenClaw ignores unknown fields, but we persist the real metadata
|
|
95
|
+
// so anyone reading models.json can see the source-of-truth values.
|
|
96
|
+
tier,
|
|
97
|
+
sweScore,
|
|
98
|
+
source: 'free-coding-models/sources.js',
|
|
89
99
|
cost: {
|
|
90
100
|
input: 0,
|
|
91
101
|
output: 0,
|
|
@@ -136,7 +136,9 @@ function getManagedProviderId(providerKey) {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
function getProviderLabel(providerKey) {
|
|
139
|
-
|
|
139
|
+
// ๐ fcm_router is now in PROVIDER_METADATA (provider-metadata.js) so all
|
|
140
|
+
// ๐ surfaces resolve to the same label. Issue #140 surfaced because this
|
|
141
|
+
// ๐ helper was the only place that knew about fcm_router.
|
|
140
142
|
return PROVIDER_METADATA[providerKey]?.label || sources[providerKey]?.name || providerKey
|
|
141
143
|
}
|
|
142
144
|
|
|
@@ -79,6 +79,18 @@ export const OPENCODE_MODEL_MAP = {
|
|
|
79
79
|
// ๐ `rateLimits` gives a quick reminder of the free-tier quota without opening a browser.
|
|
80
80
|
// ๐ `paidProviderNote` marks providers that require credits/billing despite exposing free/trial/free-tagged models.
|
|
81
81
|
export const PROVIDER_METADATA = {
|
|
82
|
+
// ๐ fcm_router is the local Smart Router Daemon โ it's not a remote provider
|
|
83
|
+
// ๐ with an API key or signup URL, but several UI surfaces look it up here
|
|
84
|
+
// ๐ to render a human label. Without this entry, the label resolves to the
|
|
85
|
+
// ๐ raw key `fcm_router` (which users read as "Unknown" โ see issue #140).
|
|
86
|
+
fcm_router: {
|
|
87
|
+
label: 'Smart Router Daemon',
|
|
88
|
+
color: chalk.rgb(80, 200, 120),
|
|
89
|
+
signupUrl: null,
|
|
90
|
+
signupHint: null,
|
|
91
|
+
rateLimits: 'Local daemon on http://127.0.0.1:19280 โ start with Shift+S',
|
|
92
|
+
noKeyNeeded: true,
|
|
93
|
+
},
|
|
82
94
|
nvidia: {
|
|
83
95
|
label: 'NVIDIA NIM',
|
|
84
96
|
color: chalk.rgb(178, 235, 190),
|