diff --git a/review-enrichment/src/analyzers/asset-weight.ts b/review-enrichment/src/analyzers/asset-weight.ts index 190a5fbe07..f142a3ebea 100644 --- a/review-enrichment/src/analyzers/asset-weight.ts +++ b/review-enrichment/src/analyzers/asset-weight.ts @@ -72,6 +72,14 @@ const BINARY_EXTS = new Set([ "node", "jar", "class", + // Serialized ML model / checkpoint weight formats — routinely hundreds of MB to multi-GB, the heaviest + // binary blobs a PR can commit, and their bytes never appear in the textual diff. + "safetensors", + "gguf", + "onnx", + "pt", + "pth", + "ckpt", ]); interface ScanOptions { diff --git a/review-enrichment/test/asset-weight.test.ts b/review-enrichment/test/asset-weight.test.ts index 620d14d4e2..01f9b6a069 100644 --- a/review-enrichment/test/asset-weight.test.ts +++ b/review-enrichment/test/asset-weight.test.ts @@ -28,6 +28,19 @@ test("isBinaryAsset flags genuine binary extensions and ignores text/case", () = assert.equal(isBinaryAsset("cache/model.zst"), true); assert.equal(isBinaryAsset("dist/bundle.tar.zst"), true); assert.equal(isBinaryAsset("cache/model.ZST"), true); + // Serialized ML model / checkpoint weight formats are heavy binary blobs (siblings of the other binaries), + // and the match stays case-insensitive. + for (const p of [ + "models/llama.safetensors", + "models/llama.gguf", + "models/resnet.onnx", + "models/model.pt", + "checkpoints/epoch10.pth", + "checkpoints/state.ckpt", + "models/LLAMA.SAFETENSORS", + ]) { + assert.equal(isBinaryAsset(p), true, p); + } // Extension match is case-insensitive. assert.equal(isBinaryAsset("assets/HERO.PNG"), true); // Text formats whose bytes are already in the diff are NOT binary assets.