|
31 | 31 | from .sync import DEFAULT_INDEX_EXTENSIONS, FileSynchronizer, parse_include_extensions |
32 | 32 |
|
33 | 33 |
|
| 34 | +def _default_embedding_model() -> str: |
| 35 | + """Pick a sensible default embedding model based on platform. |
| 36 | +
|
| 37 | + | Platform | Default model | |
| 38 | + |------------|------------------------------------------------| |
| 39 | + | NVIDIA GPU | BAAI/bge-base-en-v1.5 | |
| 40 | + | macOS | sentence-transformers/all-MiniLM-L6-v2 | |
| 41 | + | Other/CPU | sentence-transformers/all-MiniLM-L6-v2 | |
| 42 | + """ |
| 43 | + |
| 44 | + try: |
| 45 | + import torch |
| 46 | + |
| 47 | + if torch.cuda.is_available(): |
| 48 | + return "BAAI/bge-base-en-v1.5" |
| 49 | + except ImportError: |
| 50 | + pass |
| 51 | + |
| 52 | + # macOS (MPS or CPU) and all other platforms: lightweight model |
| 53 | + return "sentence-transformers/all-MiniLM-L6-v2" |
| 54 | + |
| 55 | + |
34 | 56 | def _normalize_path(path: str) -> str: |
35 | 57 | """Return absolute path string for consistent keys.""" |
36 | 58 | if not path: |
@@ -260,11 +282,12 @@ def create_parser(self) -> argparse.ArgumentParser: |
260 | 282 | choices=["hnsw", "diskann", "ivf"], |
261 | 283 | help="Backend to use (default: hnsw)", |
262 | 284 | ) |
| 285 | + _default_model = _default_embedding_model() |
263 | 286 | build_parser.add_argument( |
264 | 287 | "--embedding-model", |
265 | 288 | type=str, |
266 | | - default="facebook/contriever", |
267 | | - help="Embedding model (default: facebook/contriever)", |
| 289 | + default=_default_model, |
| 290 | + help=f"Embedding model (default: {_default_model})", |
268 | 291 | ) |
269 | 292 | build_parser.add_argument( |
270 | 293 | "--embedding-mode", |
@@ -2432,8 +2455,15 @@ async def build_index(self, args): |
2432 | 2455 | is_compact = meta.get( |
2433 | 2456 | "is_compact", meta.get("backend_kwargs", {}).get("is_compact", True) |
2434 | 2457 | ) |
| 2458 | + |
| 2459 | + # Normalize model names for comparison — e.g. "all-MiniLM-L6-v2" |
| 2460 | + # should match "sentence-transformers/all-MiniLM-L6-v2" |
| 2461 | + def _normalize_model_name(name: str) -> str: |
| 2462 | + return name.rsplit("/", 1)[-1] if name else name |
| 2463 | + |
2435 | 2464 | same_embedding = ( |
2436 | | - meta.get("embedding_model") == args.embedding_model |
| 2465 | + _normalize_model_name(meta.get("embedding_model", "")) |
| 2466 | + == _normalize_model_name(args.embedding_model) |
2437 | 2467 | and meta.get("embedding_mode") == args.embedding_mode |
2438 | 2468 | ) |
2439 | 2469 |
|
@@ -2519,6 +2549,11 @@ async def build_index(self, args): |
2519 | 2549 |
|
2520 | 2550 | else: |
2521 | 2551 | self._log_rebuild_reason(meta, args, new_paths, removed_paths, modified_paths) |
| 2552 | + # Force full reload — the partial all_texts from incremental |
| 2553 | + # path only contains changed files, not the full corpus. |
| 2554 | + all_texts = self.load_documents( |
| 2555 | + docs_paths, args.file_types, include_hidden=args.include_hidden, args=args |
| 2556 | + ) |
2522 | 2557 |
|
2523 | 2558 | # Full rebuild: load documents if not already loaded (first build or force) |
2524 | 2559 | try: |
@@ -3135,7 +3170,7 @@ async def search_documents(self, args): |
3135 | 3170 | json_results = [ |
3136 | 3171 | { |
3137 | 3172 | "id": r.id, |
3138 | | - "score": r.score, |
| 3173 | + "score": float(r.score), |
3139 | 3174 | "text": r.text, |
3140 | 3175 | "metadata": r.metadata, |
3141 | 3176 | } |
|
0 commit comments