@rigour-labs/core 4.3.3 → 4.3.4
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.
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
const DEFAULT_MODELS = {
|
|
3
3
|
claude: 'claude-opus-4-6',
|
|
4
4
|
anthropic: 'claude-sonnet-4-6',
|
|
5
|
-
openai: 'gpt-
|
|
6
|
-
gemini: 'gemini-
|
|
7
|
-
groq: 'llama-3.
|
|
5
|
+
openai: 'gpt-5-mini',
|
|
6
|
+
gemini: 'gemini-2.5-flash',
|
|
7
|
+
groq: 'llama-3.3-70b-versatile',
|
|
8
8
|
mistral: 'mistral-large-latest',
|
|
9
|
-
together: 'meta-llama/Llama-
|
|
10
|
-
fireworks: 'accounts/fireworks/models/llama-
|
|
11
|
-
deepseek: 'deepseek-
|
|
9
|
+
together: 'meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8',
|
|
10
|
+
fireworks: 'accounts/fireworks/models/llama-v3p3-70b-instruct',
|
|
11
|
+
deepseek: 'deepseek-v4',
|
|
12
12
|
perplexity: 'llama-3.1-sonar-large-128k-online',
|
|
13
13
|
ollama: 'qwen2.5-coder:7b',
|
|
14
14
|
lmstudio: 'qwen2.5-coder-7b-instruct',
|
|
@@ -13,9 +13,17 @@ export declare function getModelPath(tier: ModelTier): string;
|
|
|
13
13
|
* Get model info for a tier.
|
|
14
14
|
*/
|
|
15
15
|
export declare function getModelInfo(tier: ModelTier): ModelInfo;
|
|
16
|
+
/**
|
|
17
|
+
* Check HuggingFace for a newer model version (like antivirus signature updates).
|
|
18
|
+
* Reads latest_version.json from the RLAIF dataset repo. Non-blocking — if the
|
|
19
|
+
* check fails (offline, HF down), we silently use the cached/bundled version.
|
|
20
|
+
*
|
|
21
|
+
* Results are cached locally for 24 hours to avoid hammering HF on every run.
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkForUpdates(onProgress?: (message: string, percent?: number) => void): Promise<string>;
|
|
16
24
|
/**
|
|
17
25
|
* Download a model from HuggingFace CDN.
|
|
18
|
-
*
|
|
26
|
+
* Checks for updates first, then tries fine-tuned model, falls back to stock Qwen.
|
|
19
27
|
*/
|
|
20
28
|
export declare function downloadModel(tier: ModelTier, onProgress?: (message: string, percent?: number) => void): Promise<string>;
|
|
21
29
|
/**
|
|
@@ -6,8 +6,11 @@ import path from 'path';
|
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import { createHash } from 'crypto';
|
|
8
8
|
import { RIGOUR_DIR } from '../storage/db.js';
|
|
9
|
-
import { MODELS, FALLBACK_MODELS } from './types.js';
|
|
9
|
+
import { MODELS, FALLBACK_MODELS, VERSION_CHECK_URL, BUNDLED_MODEL_VERSION, updateModelVersion } from './types.js';
|
|
10
10
|
const MODELS_DIR = path.join(RIGOUR_DIR, 'models');
|
|
11
|
+
const VERSION_CACHE_PATH = path.join(MODELS_DIR, '.latest_version.json');
|
|
12
|
+
const VERSION_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // Check once per day
|
|
13
|
+
const VERSION_CHECK_TIMEOUT_MS = 5000; // 5s timeout — don't block startup
|
|
11
14
|
const SHA256_RE = /^[a-f0-9]{64}$/i;
|
|
12
15
|
function getModelMetadataPath(filename) {
|
|
13
16
|
return path.join(MODELS_DIR, filename + '.meta.json');
|
|
@@ -173,12 +176,66 @@ async function downloadFromUrl(tier, model, onProgress) {
|
|
|
173
176
|
throw error;
|
|
174
177
|
}
|
|
175
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Check HuggingFace for a newer model version (like antivirus signature updates).
|
|
181
|
+
* Reads latest_version.json from the RLAIF dataset repo. Non-blocking — if the
|
|
182
|
+
* check fails (offline, HF down), we silently use the cached/bundled version.
|
|
183
|
+
*
|
|
184
|
+
* Results are cached locally for 24 hours to avoid hammering HF on every run.
|
|
185
|
+
*/
|
|
186
|
+
export async function checkForUpdates(onProgress) {
|
|
187
|
+
fs.ensureDirSync(MODELS_DIR);
|
|
188
|
+
// Check local version cache first — avoid network on every run
|
|
189
|
+
try {
|
|
190
|
+
if (await fs.pathExists(VERSION_CACHE_PATH)) {
|
|
191
|
+
const cached = await fs.readJson(VERSION_CACHE_PATH);
|
|
192
|
+
const age = Date.now() - new Date(cached.checkedAt).getTime();
|
|
193
|
+
if (age < VERSION_CHECK_INTERVAL_MS && cached.version) {
|
|
194
|
+
const v = String(cached.version);
|
|
195
|
+
updateModelVersion(v);
|
|
196
|
+
return v;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Corrupted cache — proceed to network check
|
|
202
|
+
}
|
|
203
|
+
// Fetch latest version from HuggingFace (with timeout)
|
|
204
|
+
try {
|
|
205
|
+
const controller = new AbortController();
|
|
206
|
+
const timeout = setTimeout(() => controller.abort(), VERSION_CHECK_TIMEOUT_MS);
|
|
207
|
+
const response = await fetch(VERSION_CHECK_URL, { signal: controller.signal });
|
|
208
|
+
clearTimeout(timeout);
|
|
209
|
+
if (response.ok) {
|
|
210
|
+
const data = await response.json();
|
|
211
|
+
const latestVersion = String(data.version || BUNDLED_MODEL_VERSION);
|
|
212
|
+
// Cache the result locally
|
|
213
|
+
await fs.writeJson(VERSION_CACHE_PATH, {
|
|
214
|
+
version: latestVersion,
|
|
215
|
+
checkedAt: new Date().toISOString(),
|
|
216
|
+
source: 'huggingface',
|
|
217
|
+
}, { spaces: 2 }).catch(() => { });
|
|
218
|
+
// Update in-memory model definitions
|
|
219
|
+
updateModelVersion(latestVersion);
|
|
220
|
+
if (latestVersion !== BUNDLED_MODEL_VERSION) {
|
|
221
|
+
onProgress?.(`Model update available: v${latestVersion}`, 0);
|
|
222
|
+
}
|
|
223
|
+
return latestVersion;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Offline / HF down / timeout — use bundled version silently
|
|
228
|
+
}
|
|
229
|
+
return BUNDLED_MODEL_VERSION;
|
|
230
|
+
}
|
|
176
231
|
/**
|
|
177
232
|
* Download a model from HuggingFace CDN.
|
|
178
|
-
*
|
|
233
|
+
* Checks for updates first, then tries fine-tuned model, falls back to stock Qwen.
|
|
179
234
|
*/
|
|
180
235
|
export async function downloadModel(tier, onProgress) {
|
|
181
236
|
fs.ensureDirSync(MODELS_DIR);
|
|
237
|
+
// Check for newer model version (non-blocking, cached 24h)
|
|
238
|
+
await checkForUpdates(onProgress);
|
|
182
239
|
if (await isModelCached(tier)) {
|
|
183
240
|
onProgress?.(`Model ${MODELS[tier].name} already cached`, 100);
|
|
184
241
|
return getModelPath(tier);
|
|
@@ -62,7 +62,7 @@ export interface DeepAnalysisResult {
|
|
|
62
62
|
* Available model tiers.
|
|
63
63
|
*
|
|
64
64
|
* - deep: Qwen2.5-Coder-1.5B fine-tuned — full power, company-hosted
|
|
65
|
-
* - lite:
|
|
65
|
+
* - lite: Qwen2.5-Coder-0.5B fine-tuned — lightweight, ships as default CLI sidecar
|
|
66
66
|
* - legacy: Qwen2.5-Coder-0.5B fine-tuned — previous default, reproducibility
|
|
67
67
|
*/
|
|
68
68
|
export type ModelTier = 'deep' | 'lite' | 'legacy';
|
|
@@ -78,13 +78,24 @@ export interface ModelInfo {
|
|
|
78
78
|
sizeHuman: string;
|
|
79
79
|
}
|
|
80
80
|
/**
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
81
|
+
* Minimum bundled model version — used as fallback when the auto-update
|
|
82
|
+
* check fails (offline, HF down, first run). The RLAIF training pipeline
|
|
83
|
+
* publishes new versions to HuggingFace and updates latest_version.json.
|
|
84
|
+
* At startup, model-manager checks HF for the latest version and downloads
|
|
85
|
+
* it automatically (like antivirus signature updates).
|
|
84
86
|
*/
|
|
85
|
-
export declare const
|
|
86
|
-
/**
|
|
87
|
+
export declare const BUNDLED_MODEL_VERSION = "1";
|
|
88
|
+
/** HuggingFace dataset repo where latest_version.json lives */
|
|
89
|
+
export declare const VERSION_CHECK_URL = "https://huggingface.co/datasets/rigour-labs/rigour-rlaif-data/resolve/main/latest_version.json";
|
|
90
|
+
/** Build model info for a given tier and version */
|
|
91
|
+
export declare function buildModelInfo(tier: ModelTier, version: string): ModelInfo;
|
|
92
|
+
/** Current model definitions — initialized with bundled version, updated at runtime */
|
|
87
93
|
export declare const MODELS: Record<ModelTier, ModelInfo>;
|
|
94
|
+
/**
|
|
95
|
+
* Update MODELS in-place to point to a newer version.
|
|
96
|
+
* Called by model-manager after checking latest_version.json.
|
|
97
|
+
*/
|
|
98
|
+
export declare function updateModelVersion(version: string): void;
|
|
88
99
|
/**
|
|
89
100
|
* Fallback stock models — used when fine-tuned model is not yet
|
|
90
101
|
* available on HuggingFace (initial setup / first-time users).
|
package/dist/inference/types.js
CHANGED
|
@@ -1,36 +1,46 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Minimum bundled model version — used as fallback when the auto-update
|
|
3
|
+
* check fails (offline, HF down, first run). The RLAIF training pipeline
|
|
4
|
+
* publishes new versions to HuggingFace and updates latest_version.json.
|
|
5
|
+
* At startup, model-manager checks HF for the latest version and downloads
|
|
6
|
+
* it automatically (like antivirus signature updates).
|
|
5
7
|
*/
|
|
6
|
-
export const
|
|
7
|
-
/**
|
|
8
|
+
export const BUNDLED_MODEL_VERSION = '1';
|
|
9
|
+
/** HuggingFace dataset repo where latest_version.json lives */
|
|
10
|
+
export const VERSION_CHECK_URL = 'https://huggingface.co/datasets/rigour-labs/rigour-rlaif-data/resolve/main/latest_version.json';
|
|
11
|
+
/** Build model info for a given tier and version */
|
|
12
|
+
export function buildModelInfo(tier, version) {
|
|
13
|
+
const meta = {
|
|
14
|
+
deep: { base: 'Qwen2.5-Coder-1.5B', size: 900_000_000, sizeH: '900MB' },
|
|
15
|
+
lite: { base: 'Qwen2.5-Coder-0.5B', size: 500_000_000, sizeH: '500MB' },
|
|
16
|
+
legacy: { base: 'Qwen2.5-Coder-0.5B', size: 350_000_000, sizeH: '350MB' },
|
|
17
|
+
};
|
|
18
|
+
const m = meta[tier];
|
|
19
|
+
return {
|
|
20
|
+
tier,
|
|
21
|
+
name: `Rigour-${tier[0].toUpperCase() + tier.slice(1)}-v${version} (${m.base} fine-tuned)`,
|
|
22
|
+
filename: `rigour-${tier}-v${version}-q4_k_m.gguf`,
|
|
23
|
+
url: `https://huggingface.co/rigour-labs/rigour-${tier}-v${version}-gguf/resolve/main/rigour-${tier}-v${version}-q4_k_m.gguf`,
|
|
24
|
+
sizeBytes: m.size,
|
|
25
|
+
sizeHuman: m.sizeH,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Current model definitions — initialized with bundled version, updated at runtime */
|
|
8
29
|
export const MODELS = {
|
|
9
|
-
deep:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
filename: `rigour-deep-v${MODEL_VERSION}-q4_k_m.gguf`,
|
|
13
|
-
url: `https://huggingface.co/rigour-labs/rigour-deep-v1-gguf/resolve/main/rigour-deep-v${MODEL_VERSION}-q4_k_m.gguf`,
|
|
14
|
-
sizeBytes: 900_000_000,
|
|
15
|
-
sizeHuman: '900MB',
|
|
16
|
-
},
|
|
17
|
-
lite: {
|
|
18
|
-
tier: 'lite',
|
|
19
|
-
name: 'Rigour-Lite-v1 (Qwen3.5-0.8B fine-tuned)',
|
|
20
|
-
filename: `rigour-lite-v${MODEL_VERSION}-q4_k_m.gguf`,
|
|
21
|
-
url: `https://huggingface.co/rigour-labs/rigour-lite-v1-gguf/resolve/main/rigour-lite-v${MODEL_VERSION}-q4_k_m.gguf`,
|
|
22
|
-
sizeBytes: 500_000_000,
|
|
23
|
-
sizeHuman: '500MB',
|
|
24
|
-
},
|
|
25
|
-
legacy: {
|
|
26
|
-
tier: 'legacy',
|
|
27
|
-
name: 'Rigour-Legacy-v1 (Qwen2.5-Coder-0.5B fine-tuned)',
|
|
28
|
-
filename: `rigour-legacy-v${MODEL_VERSION}-q4_k_m.gguf`,
|
|
29
|
-
url: `https://huggingface.co/rigour-labs/rigour-legacy-v1-gguf/resolve/main/rigour-legacy-v${MODEL_VERSION}-q4_k_m.gguf`,
|
|
30
|
-
sizeBytes: 350_000_000,
|
|
31
|
-
sizeHuman: '350MB',
|
|
32
|
-
},
|
|
30
|
+
deep: buildModelInfo('deep', BUNDLED_MODEL_VERSION),
|
|
31
|
+
lite: buildModelInfo('lite', BUNDLED_MODEL_VERSION),
|
|
32
|
+
legacy: buildModelInfo('legacy', BUNDLED_MODEL_VERSION),
|
|
33
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* Update MODELS in-place to point to a newer version.
|
|
36
|
+
* Called by model-manager after checking latest_version.json.
|
|
37
|
+
*/
|
|
38
|
+
export function updateModelVersion(version) {
|
|
39
|
+
for (const tier of ['deep', 'lite', 'legacy']) {
|
|
40
|
+
const updated = buildModelInfo(tier, version);
|
|
41
|
+
MODELS[tier] = updated;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
34
44
|
/**
|
|
35
45
|
* Fallback stock models — used when fine-tuned model is not yet
|
|
36
46
|
* available on HuggingFace (initial setup / first-time users).
|
|
@@ -46,9 +56,9 @@ export const FALLBACK_MODELS = {
|
|
|
46
56
|
},
|
|
47
57
|
lite: {
|
|
48
58
|
tier: 'lite',
|
|
49
|
-
name: '
|
|
50
|
-
filename: '
|
|
51
|
-
url: 'https://huggingface.co/Qwen/
|
|
59
|
+
name: 'Qwen2.5-Coder-0.5B-Instruct (stock)',
|
|
60
|
+
filename: 'qwen2.5-coder-0.5b-instruct-q4_k_m.gguf',
|
|
61
|
+
url: 'https://huggingface.co/Qwen/Qwen2.5-Coder-0.5B-Instruct-GGUF/resolve/main/qwen2.5-coder-0.5b-instruct-q4_k_m.gguf',
|
|
52
62
|
sizeBytes: 500_000_000,
|
|
53
63
|
sizeHuman: '500MB',
|
|
54
64
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rigour-labs/core",
|
|
3
|
-
"version": "4.3.
|
|
3
|
+
"version": "4.3.4",
|
|
4
4
|
"description": "Deterministic quality gate engine for AI-generated code. AST analysis, drift detection, and Fix Packet generation across TypeScript, JavaScript, Python, Go, Ruby, and C#.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://rigour.run",
|
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
"@xenova/transformers": "^2.17.2",
|
|
60
60
|
"better-sqlite3": "^11.0.0",
|
|
61
61
|
"openai": "^4.104.0",
|
|
62
|
-
"@rigour-labs/brain-darwin-arm64": "4.3.
|
|
63
|
-
"@rigour-labs/brain-
|
|
64
|
-
"@rigour-labs/brain-
|
|
65
|
-
"@rigour-labs/brain-
|
|
66
|
-
"@rigour-labs/brain-
|
|
62
|
+
"@rigour-labs/brain-darwin-arm64": "4.3.4",
|
|
63
|
+
"@rigour-labs/brain-darwin-x64": "4.3.4",
|
|
64
|
+
"@rigour-labs/brain-linux-x64": "4.3.4",
|
|
65
|
+
"@rigour-labs/brain-linux-arm64": "4.3.4",
|
|
66
|
+
"@rigour-labs/brain-win-x64": "4.3.4"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@types/better-sqlite3": "^7.6.12",
|