grepmax 0.21.0 → 0.21.1

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.
@@ -10,7 +10,7 @@
10
10
  "name": "grepmax",
11
11
  "source": "./plugins/grepmax",
12
12
  "description": "Semantic code search for Claude Code. Automatically indexes your project and provides intelligent search capabilities.",
13
- "version": "0.21.0",
13
+ "version": "0.21.1",
14
14
  "author": {
15
15
  "name": "Robert Owens",
16
16
  "email": "robowens@me.com"
package/README.md CHANGED
@@ -289,6 +289,45 @@ All data lives in `~/.gmax/`:
289
289
  }
290
290
  ```
291
291
 
292
+ ### Model Tier
293
+
294
+ gmax embeds with IBM's Granite r2 code-embedding models. Two tiers are available:
295
+
296
+ | Tier | Model | Dim | Params |
297
+ | --- | --- | --- | --- |
298
+ | `small` (default) | `granite-embedding-small-english-r2` | 384 | 47M |
299
+ | `standard` | `granite-embedding-english-r2` | 768 | 149M |
300
+
301
+ **384d is the default — and benchmarking says keep it.** On gmax's own 97-case
302
+ retrieval eval (`pnpm bench:recall`), the larger 768d model scored **~10 points
303
+ *worse* on Recall@10** than 384d, consistently on both the MLX GPU and ONNX CPU
304
+ embedding paths, with and without ColBERT rerank:
305
+
306
+ | Model | Recall@10 | MRR@10 |
307
+ | --- | --- | --- |
308
+ | `small` / 384d | **0.72** | **0.51** |
309
+ | `standard` / 768d | 0.62 | 0.44 |
310
+
311
+ <sub>gmax repo, 97 cases, MLX GPU, rerank off (the shipped default). The CPU/q4
312
+ path and the rerank-on path show the same ~0.10 Recall@10 gap, so it isn't a
313
+ quantization artifact — the bigger model just retrieves worse on code here.</sub>
314
+
315
+ Bigger isn't better for this workload: 768d roughly doubles embedding compute,
316
+ worker RAM, and dense-vector storage while *lowering* recall on code search.
317
+ Unless you have a measured reason to switch (e.g. a recall complaint on a very
318
+ large repo — benchmark it first), stay on 384d.
319
+
320
+ To change tiers:
321
+
322
+ ```bash
323
+ gmax config --model-tier standard # a dim change needs a full re-embed
324
+ gmax repair --rebuild # drops the shared table, re-embeds every project at the new dim
325
+ ```
326
+
327
+ A vector-dimension change can't be applied by a per-project `gmax index --reset`
328
+ — the shared `chunks` table is fixed-width, so `gmax repair --rebuild` is the
329
+ sanctioned path.
330
+
292
331
  ### Ignoring Files
293
332
 
294
333
  gmax respects `.gitignore` and `.gmaxignore`:
@@ -339,6 +378,8 @@ GMAX_EVAL_RERANK=1 pnpm bench:oss # toggle ColBERT rerank
339
378
 
340
379
  The OSS bench requires the fixture repos to be indexed first — see [`docs/known-limitations.md`](docs/known-limitations.md) for the most recent rerank-on-vs-off comparison across 4 datasets / 131 cases.
341
380
 
381
+ `pnpm bench:recall` also drives the model-tier comparison behind the 384d default — see [Model Tier](#model-tier) for why the larger 768d model is *not* the default.
382
+
342
383
  ## Attribution
343
384
 
344
385
  grepmax is built upon the foundation of [mgrep](https://github.com/mixedbread-ai/mgrep) by MixedBread. See the [NOTICE](NOTICE) file for details.
@@ -84,6 +84,7 @@ Examples:
84
84
  const newMode = (_c = options.embedMode) !== null && _c !== void 0 ? _c : globalConfig.embedMode;
85
85
  const tier = (_d = config_1.MODEL_TIERS[newTier]) !== null && _d !== void 0 ? _d : config_1.MODEL_TIERS.small;
86
86
  const tierChanged = newTier !== globalConfig.modelTier;
87
+ const dimChanged = tier.vectorDim !== globalConfig.vectorDim;
87
88
  (0, index_config_1.writeGlobalConfig)({
88
89
  modelTier: newTier,
89
90
  vectorDim: tier.vectorDim,
@@ -98,7 +99,12 @@ Examples:
98
99
  });
99
100
  console.log(`Updated: embed-mode=${newMode}, model-tier=${newTier} (${tier.vectorDim}d)`);
100
101
  if (tierChanged) {
101
- console.log("⚠️ Model tier changed run `gmax index --reset` to rebuild with new dimensions.");
102
+ // A dimension change can't be fixed by a per-project `gmax index --reset`:
103
+ // the shared `chunks` table is fixed-width, so it must be dropped and
104
+ // rebuilt. A same-dim model swap (future tiers) can use a per-project reset.
105
+ console.log(dimChanged
106
+ ? `⚠️ Model tier changed (${globalConfig.vectorDim}d → ${tier.vectorDim}d). The shared vector table is fixed-width — run \`${config_1.REBUILD_COMMAND}\` to drop it and re-embed every project at the new dim.`
107
+ : "⚠️ Model tier changed — run `gmax index --reset` per project to re-embed with the new model.");
102
108
  }
103
109
  yield (0, exit_1.gracefulExit)();
104
110
  }));
@@ -104,7 +104,9 @@ function maybeWarnStaleEmbedding(projectRoot, opts) {
104
104
  `current_dim=${gap.toDim}`,
105
105
  `dim_changed=${gap.dimChanged}`,
106
106
  `severity=${gap.severity}`,
107
- "fix=gmax index --reset",
107
+ // A dim change needs the global rebuild (shared table is fixed-width); a
108
+ // same-dim model swap can use a per-project reset.
109
+ `fix=${gap.dimChanged ? config_1.REBUILD_COMMAND : "gmax index --reset"}`,
108
110
  ].join("\t");
109
111
  process.stderr.write(`${fields}\n`);
110
112
  return;
@@ -113,7 +115,10 @@ function maybeWarnStaleEmbedding(projectRoot, opts) {
113
115
  const detail = gap.dimChanged
114
116
  ? `vector dim ${gap.fromDim}→${gap.toDim} (incompatible — scores invalid until re-embed)`
115
117
  : `model '${gap.fromModel}'→'${gap.toModel}' (same dim; results mix models until re-embed)`;
116
- process.stderr.write(`${label} gmax: '${name}' indexed with embedding ${detail}. Run 'gmax index --reset'. (silence: GMAX_NO_STALE_HINT=1)\n`);
118
+ const fix = gap.dimChanged
119
+ ? `Run '${config_1.REBUILD_COMMAND}'`
120
+ : "Run 'gmax index --reset'";
121
+ process.stderr.write(`${label} gmax: '${name}' indexed with embedding ${detail}. ${fix}. (silence: GMAX_NO_STALE_HINT=1)\n`);
117
122
  }
118
123
  /**
119
124
  * Cross-project guard: when a `--all-projects` / `--projects` search spans
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
4
4
  "author": "Robert Owens <78518764+reowens@users.noreply.github.com>",
5
5
  "homepage": "https://github.com/reowens/grepmax",
6
6
  "bugs": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grepmax",
3
- "version": "0.21.0",
3
+ "version": "0.21.1",
4
4
  "description": "Semantic code search for Claude Code. Automatically indexes your project and provides intelligent search capabilities.",
5
5
  "author": {
6
6
  "name": "Robert Owens",