get-claudia 1.35.0 → 1.35.2
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.
|
@@ -331,14 +331,104 @@ def main():
|
|
|
331
331
|
old_dim = int(old_dims_row[0]["value"]) if old_dims_row else 384
|
|
332
332
|
|
|
333
333
|
if old_model == new_model and old_dim == new_dim:
|
|
334
|
-
|
|
335
|
-
|
|
334
|
+
# No mismatch -- offer interactive model selection
|
|
335
|
+
print(f"\nCurrent embedding model: {old_model} ({old_dim}D)")
|
|
336
|
+
print()
|
|
337
|
+
print("Available models:")
|
|
338
|
+
models_info = [
|
|
339
|
+
("1", "all-minilm:l6-v2", 384, " 23MB", "Fast, good baseline"),
|
|
340
|
+
("2", "nomic-embed-text", 768, " 274MB", "Better retrieval (+6%)"),
|
|
341
|
+
("3", "mxbai-embed-large", 1024, " 669MB", "Best accuracy, larger"),
|
|
342
|
+
]
|
|
343
|
+
for num, name, dim, size, desc in models_info:
|
|
344
|
+
current = " (current)" if name == old_model else ""
|
|
345
|
+
print(f" {num}) {name:<20s} {dim}D {size} {desc}{current}")
|
|
346
|
+
print(" 4) Cancel")
|
|
347
|
+
print()
|
|
348
|
+
choice = input("Switch to [1-4, default=4]: ").strip()
|
|
349
|
+
|
|
350
|
+
model_map = {
|
|
351
|
+
"1": ("all-minilm:l6-v2", 384),
|
|
352
|
+
"2": ("nomic-embed-text", 768),
|
|
353
|
+
"3": ("mxbai-embed-large", 1024),
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if choice not in model_map:
|
|
357
|
+
print("No changes made.")
|
|
358
|
+
return
|
|
359
|
+
|
|
360
|
+
new_model, new_dim = model_map[choice]
|
|
361
|
+
|
|
362
|
+
if new_model == old_model and new_dim == old_dim:
|
|
363
|
+
print(f"Already using {new_model}. No changes needed.")
|
|
364
|
+
return
|
|
365
|
+
|
|
366
|
+
# Update config.json with the user's choice
|
|
367
|
+
config_path = Path.home() / ".claudia" / "config.json"
|
|
368
|
+
try:
|
|
369
|
+
if config_path.exists():
|
|
370
|
+
with open(config_path) as f:
|
|
371
|
+
cfg_data = _json.load(f)
|
|
372
|
+
else:
|
|
373
|
+
cfg_data = {}
|
|
374
|
+
cfg_data["embedding_model"] = new_model
|
|
375
|
+
cfg_data["embedding_dimensions"] = new_dim
|
|
376
|
+
with open(config_path, "w") as f:
|
|
377
|
+
_json.dump(cfg_data, f, indent=2)
|
|
378
|
+
print(f"\nConfig updated: {new_model} ({new_dim}D)")
|
|
379
|
+
except Exception as e:
|
|
380
|
+
print(f"Warning: Could not update config.json: {e}")
|
|
381
|
+
|
|
382
|
+
# Reinitialize embedding service with new model
|
|
383
|
+
svc.model = new_model
|
|
384
|
+
svc.dimensions = new_dim
|
|
385
|
+
svc._available = None # Force re-check
|
|
336
386
|
|
|
337
387
|
# Pre-flight: verify Ollama is running and model is available
|
|
338
388
|
if not svc.is_available_sync():
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
389
|
+
# Distinguish: Ollama not running vs model not pulled
|
|
390
|
+
import subprocess
|
|
391
|
+
import httpx
|
|
392
|
+
|
|
393
|
+
ollama_running = False
|
|
394
|
+
try:
|
|
395
|
+
resp = httpx.get(f"{svc.host}/api/tags", timeout=5)
|
|
396
|
+
ollama_running = resp.status_code == 200
|
|
397
|
+
except Exception:
|
|
398
|
+
pass
|
|
399
|
+
|
|
400
|
+
if not ollama_running:
|
|
401
|
+
print(f"Error: Ollama is not running.")
|
|
402
|
+
print(f"Please start Ollama and try again.")
|
|
403
|
+
sys.exit(1)
|
|
404
|
+
|
|
405
|
+
# Ollama is running but model is missing -- offer to pull it
|
|
406
|
+
print(f"\nThe model '{new_model}' is not installed in Ollama.")
|
|
407
|
+
pull_choice = input(f"Download it now? (Y/n): ").strip().lower()
|
|
408
|
+
if pull_choice in ("", "y", "yes"):
|
|
409
|
+
print(f"Downloading {new_model}... (this may take a minute)")
|
|
410
|
+
try:
|
|
411
|
+
result = subprocess.run(
|
|
412
|
+
["ollama", "pull", new_model],
|
|
413
|
+
capture_output=False,
|
|
414
|
+
text=True,
|
|
415
|
+
)
|
|
416
|
+
if result.returncode != 0:
|
|
417
|
+
print(f"Error: Failed to pull {new_model}.")
|
|
418
|
+
sys.exit(1)
|
|
419
|
+
except FileNotFoundError:
|
|
420
|
+
print("Error: 'ollama' command not found. Please install Ollama.")
|
|
421
|
+
sys.exit(1)
|
|
422
|
+
|
|
423
|
+
# Re-check availability after pull
|
|
424
|
+
svc._available = None
|
|
425
|
+
if not svc.is_available_sync():
|
|
426
|
+
print(f"Error: Model still not available after pull.")
|
|
427
|
+
sys.exit(1)
|
|
428
|
+
print(f"Model '{new_model}' ready.")
|
|
429
|
+
else:
|
|
430
|
+
print("Migration cancelled.")
|
|
431
|
+
return
|
|
342
432
|
|
|
343
433
|
# Count embeddings across all tables
|
|
344
434
|
embedding_counts = {}
|
|
@@ -359,7 +449,7 @@ def main():
|
|
|
359
449
|
|
|
360
450
|
# Count source data to re-embed
|
|
361
451
|
mem_count_rows = db.execute(
|
|
362
|
-
"SELECT COUNT(*) as cnt FROM memories WHERE
|
|
452
|
+
"SELECT COUNT(*) as cnt FROM memories WHERE invalidated_at IS NULL",
|
|
363
453
|
fetch=True,
|
|
364
454
|
)
|
|
365
455
|
ent_count_rows = db.execute(
|
|
@@ -441,7 +531,7 @@ def main():
|
|
|
441
531
|
# 3a. Memory embeddings (largest, most important)
|
|
442
532
|
if mem_count > 0:
|
|
443
533
|
memories = db.execute(
|
|
444
|
-
"SELECT id, content FROM memories WHERE
|
|
534
|
+
"SELECT id, content FROM memories WHERE invalidated_at IS NULL",
|
|
445
535
|
fetch=True,
|
|
446
536
|
)
|
|
447
537
|
success = 0
|
|
@@ -220,7 +220,7 @@ class TestMigration:
|
|
|
220
220
|
|
|
221
221
|
# Simulate re-embedding (what --migrate-embeddings does in step 3)
|
|
222
222
|
memories = database.execute(
|
|
223
|
-
"SELECT id, content FROM memories WHERE
|
|
223
|
+
"SELECT id, content FROM memories WHERE invalidated_at IS NULL",
|
|
224
224
|
fetch=True,
|
|
225
225
|
)
|
|
226
226
|
for row in memories:
|