own-rag-cli 0.0.11-snapshot → 0.0.13-snapshot

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.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # MCP binary checksum (SHA-256, payload without shebang): `286e52abcbc295893b501fc8aae092420c452a4d3a4242e25c88e646398190b6`
1
+ # MCP binary checksum (SHA-256, payload without shebang): `c74a07c0d8349fad54f3c5aa876296f9ed20239ffa0f2e6483e57796c7831e2a`
2
2
 
3
3
  # own-rag
4
4
 
@@ -60,10 +60,15 @@ rag run /path/to/project ".js,.py,.md,.java" # indexa só essas extensões
60
60
  rag run /path/to/project --skip-index --extensions ".md,.txt"
61
61
  rag monitor # interactive Chroma monitor
62
62
  rag monitor full # full monitor dashboard
63
- rag remove # full local uninstall (double confirmation)
64
- rag remove --force # uninstall without confirmation prompts
63
+ rag remove # uninstall local setup (preserves downloaded models)
64
+ rag remove --force # uninstall setup without confirmation prompts
65
+ rag clean models # list cached models and remove one or 'all' (double confirmation)
65
66
  ```
66
67
 
68
+ Notes:
69
+ - `rag remove` keeps downloaded model cache.
70
+ - Use `rag clean models` to remove selected model cache entries.
71
+
67
72
  About extension filter in `rag run`:
68
73
  - You can pass extensions as CSV in the 3rd/4th argument, for example:
69
74
  - `rag run ./path .js,.py,.md,.java`
package/README.pt-br.md CHANGED
@@ -55,10 +55,15 @@ chmod +x rag-setup-macos.run
55
55
  rag run /caminho/do/projeto # setup completo + indexação
56
56
  rag monitor # monitor interativo do Chroma
57
57
  rag monitor full # painel completo do monitor
58
- rag remove # desinstalação completa local (dupla confirmação)
59
- rag remove --force # desinstala sem prompts de confirmação
58
+ rag remove # desinstala setup local (preserva modelos baixados)
59
+ rag remove --force # desinstala setup sem prompts de confirmação
60
+ rag clean models # lista modelos em cache e remove um ou 'all' (dupla confirmação)
60
61
  ```
61
62
 
63
+ Notas:
64
+ - `rag remove` mantém o cache de modelos baixados.
65
+ - Use `rag clean models` para limpar modelos específicos ou todos (`all`).
66
+
62
67
  ## Indexacao a partir de URL (HTTP/HTTPS)
63
68
 
64
69
  Agora o `rag run` aceita URL remota alem de pasta local.
package/bin/mcp_server.py CHANGED
@@ -16,6 +16,8 @@ import json
16
16
  import logging
17
17
  import getpass
18
18
  import shutil
19
+ import threading
20
+ import time
19
21
  from collections.abc import Iterator
20
22
  from concurrent.futures import ThreadPoolExecutor, as_completed
21
23
  from dataclasses import dataclass
@@ -392,6 +394,21 @@ MAX_FILE_SIZE_BYTES = 500 * 1024 # 500 KB
392
394
  TOP_K_RESULTS = 7
393
395
  MAX_QUERY_RESULTS = 30
394
396
 
397
+ WARMUP_ENABLED = os.environ.get("MCP_WARMUP_ENABLED", "true").strip().lower() in {"1", "true", "yes", "on"}
398
+ WARMUP_MODE = os.environ.get("MCP_WARMUP_MODE", "single").strip().lower()
399
+ if WARMUP_MODE not in {"single", "ensemble"}:
400
+ WARMUP_MODE = "single"
401
+ WARMUP_QUERY = os.environ.get("MCP_WARMUP_QUERY", "warmup semantic search")
402
+ WARMUP_TOP_K = max(1, min(_parse_int(os.environ.get("MCP_WARMUP_TOP_K", "1"), 1, min_value=1), 20))
403
+
404
+ KEEPALIVE_ENABLED = os.environ.get("MCP_KEEPALIVE_ENABLED", "true").strip().lower() in {"1", "true", "yes", "on"}
405
+ KEEPALIVE_MODE = os.environ.get("MCP_KEEPALIVE_MODE", "single").strip().lower()
406
+ if KEEPALIVE_MODE not in {"single", "ensemble"}:
407
+ KEEPALIVE_MODE = "single"
408
+ KEEPALIVE_QUERY = os.environ.get("MCP_KEEPALIVE_QUERY", WARMUP_QUERY)
409
+ KEEPALIVE_TOP_K = max(1, min(_parse_int(os.environ.get("MCP_KEEPALIVE_TOP_K", "1"), 1, min_value=1), 20))
410
+ KEEPALIVE_INTERVAL_SEC = _parse_int(os.environ.get("MCP_KEEPALIVE_INTERVAL_SEC", "600"), 600, min_value=60)
411
+
395
412
  # Filtros de varredura
396
413
  IGNORED_DIRS = {
397
414
  ".git", "node_modules", "__pycache__", ".venv", "venv", "env",
@@ -1339,6 +1356,88 @@ def _run_ensemble_mode(query: str, top_k: int) -> tuple[list[FusedHit], list[str
1339
1356
  return reranked_hits, branch_errors, rerank_applied, rerank_error
1340
1357
 
1341
1358
 
1359
+ def _execute_background_search(mode: str, query: str, top_k: int, source: str) -> None:
1360
+ started = time.perf_counter()
1361
+ try:
1362
+ if mode == "ensemble":
1363
+ hits, branch_errors, rerank_applied, rerank_error = _run_ensemble_mode(query, top_k)
1364
+ else:
1365
+ hits, branch_errors, rerank_applied, rerank_error = _run_single_mode(query, top_k)
1366
+
1367
+ elapsed_ms = int((time.perf_counter() - started) * 1000)
1368
+ log.info(
1369
+ "%s concluido: mode=%s top_k=%s elapsed_ms=%s hits=%s branch_errors=%s rerank=%s",
1370
+ source,
1371
+ mode,
1372
+ top_k,
1373
+ elapsed_ms,
1374
+ len(hits),
1375
+ len(branch_errors),
1376
+ rerank_applied,
1377
+ )
1378
+ _log_tool_usage(
1379
+ event="maintenance_call",
1380
+ tool_name=source,
1381
+ details={
1382
+ "status": "ok",
1383
+ "mode": mode,
1384
+ "query_len": len(query),
1385
+ "top_k": top_k,
1386
+ "elapsed_ms": elapsed_ms,
1387
+ "result_count": len(hits),
1388
+ "branch_errors": len(branch_errors),
1389
+ "rerank_applied": rerank_applied,
1390
+ "rerank_error": rerank_error,
1391
+ },
1392
+ )
1393
+ except Exception as e:
1394
+ elapsed_ms = int((time.perf_counter() - started) * 1000)
1395
+ log.warning("%s falhou após %sms: %s", source, elapsed_ms, e)
1396
+ _log_tool_usage(
1397
+ event="maintenance_call",
1398
+ tool_name=source,
1399
+ details={
1400
+ "status": "error",
1401
+ "mode": mode,
1402
+ "query_len": len(query),
1403
+ "top_k": top_k,
1404
+ "elapsed_ms": elapsed_ms,
1405
+ "error": str(e),
1406
+ },
1407
+ )
1408
+
1409
+
1410
+ _keepalive_thread: threading.Thread | None = None
1411
+ _keepalive_stop_event = threading.Event()
1412
+
1413
+
1414
+ def _start_keepalive_thread() -> None:
1415
+ global _keepalive_thread
1416
+ if not KEEPALIVE_ENABLED:
1417
+ log.info("Keepalive desabilitado (MCP_KEEPALIVE_ENABLED=false).")
1418
+ return
1419
+ if _keepalive_thread is not None and _keepalive_thread.is_alive():
1420
+ return
1421
+
1422
+ def _runner() -> None:
1423
+ log.info(
1424
+ "Keepalive iniciado: intervalo=%ss mode=%s top_k=%s",
1425
+ KEEPALIVE_INTERVAL_SEC,
1426
+ KEEPALIVE_MODE,
1427
+ KEEPALIVE_TOP_K,
1428
+ )
1429
+ while not _keepalive_stop_event.wait(KEEPALIVE_INTERVAL_SEC):
1430
+ _execute_background_search(
1431
+ mode=KEEPALIVE_MODE,
1432
+ query=KEEPALIVE_QUERY,
1433
+ top_k=KEEPALIVE_TOP_K,
1434
+ source="semantic_search_keepalive",
1435
+ )
1436
+
1437
+ _keepalive_thread = threading.Thread(target=_runner, name="rag-keepalive", daemon=True)
1438
+ _keepalive_thread.start()
1439
+
1440
+
1342
1441
  # ---------------------------------------------------------------------------
1343
1442
  # Servidor MCP via FastMCP
1344
1443
  # ---------------------------------------------------------------------------
@@ -1799,6 +1898,16 @@ if __name__ == "__main__":
1799
1898
  log.info("Reranker: %s (enabled=%s, quant=%s)", RERANK_MODEL_ID, RERANK_ENABLED, RERANKER_QUANTIZATION)
1800
1899
  log.info("Pasta de modelos locais: %s", MODEL_DIR)
1801
1900
  log.info("Uso MCP será registrado em: %s", MCP_USAGE_LOG_PATH)
1901
+ log.info(
1902
+ "Warmup: enabled=%s mode=%s top_k=%s | Keepalive: enabled=%s interval=%ss mode=%s top_k=%s",
1903
+ WARMUP_ENABLED,
1904
+ WARMUP_MODE,
1905
+ WARMUP_TOP_K,
1906
+ KEEPALIVE_ENABLED,
1907
+ KEEPALIVE_INTERVAL_SEC,
1908
+ KEEPALIVE_MODE,
1909
+ KEEPALIVE_TOP_K,
1910
+ )
1802
1911
 
1803
1912
  # Pré-aquece somente conexão Chroma; modelos ficam lazy para poupar RAM.
1804
1913
  try:
@@ -1810,4 +1919,16 @@ if __name__ == "__main__":
1810
1919
  log.error("Falha ao inicializar ChromaDB: %s", e)
1811
1920
  log.error("O servidor continuará, mas as ferramentas retornarão erro até o ChromaDB estar disponível.")
1812
1921
 
1922
+ if WARMUP_ENABLED:
1923
+ _execute_background_search(
1924
+ mode=WARMUP_MODE,
1925
+ query=WARMUP_QUERY,
1926
+ top_k=WARMUP_TOP_K,
1927
+ source="semantic_search_warmup",
1928
+ )
1929
+ else:
1930
+ log.info("Warmup desabilitado (MCP_WARMUP_ENABLED=false).")
1931
+
1932
+ _start_keepalive_thread()
1933
+
1813
1934
  mcp.run(transport="stdio")
@@ -16,6 +16,8 @@ MONITOR_SRC="${PACKAGE_ROOT}/chroma_monitor.sh"
16
16
  MONITOR_DEST="${LOCAL_BIN_DIR}/chroma_monitor.sh"
17
17
  REMOVE_SRC="${PACKAGE_ROOT}/bin/rag-remove.sh"
18
18
  REMOVE_DEST="${LOCAL_BIN_DIR}/rag-remove.sh"
19
+ CLEAN_MODELS_SRC="${PACKAGE_ROOT}/bin/rag-clean-models.sh"
20
+ CLEAN_MODELS_DEST="${LOCAL_BIN_DIR}/rag-clean-models.sh"
19
21
  OWN_RAG_CONFIG_FILE="${HOME}/.own-rag-cli.json"
20
22
  MCP_SERVER_COMMAND="${HOME}/.local/bin/mcp-rag-server"
21
23
  CLAUDE_CONFIG_FILE="${HOME}/.claude.json"
@@ -359,6 +361,12 @@ if [[ -f "${REMOVE_SRC}" ]]; then
359
361
  log_info "Remoção copiada: ${REMOVE_DEST}"
360
362
  fi
361
363
 
364
+ if [[ -f "${CLEAN_MODELS_SRC}" ]]; then
365
+ cp "${CLEAN_MODELS_SRC}" "${CLEAN_MODELS_DEST}"
366
+ chmod +x "${CLEAN_MODELS_DEST}"
367
+ log_info "Limpeza de modelos copiada: ${CLEAN_MODELS_DEST}"
368
+ fi
369
+
362
370
  DOCKER_COMPOSE_CMD=""
363
371
  if command -v docker >/dev/null 2>&1; then
364
372
  if docker compose version >/dev/null 2>&1; then
@@ -399,4 +407,4 @@ if [[ -f "${HOME}/.profile" ]]; then
399
407
  source "${HOME}/.profile" || true
400
408
  fi
401
409
 
402
- log_info "Postinstall concluído. Use: rag run [path] | rag monitor | rag remove"
410
+ log_info "Postinstall concluído. Use: rag run [path] | rag monitor | rag remove | rag clean models"
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ usage() {
5
+ cat <<'EOF'
6
+ Uso:
7
+ rag clean models
8
+
9
+ Descrição:
10
+ Lista os modelos baixados em cache e permite apagar um modelo específico
11
+ ou todos ("all"), com confirmação dupla.
12
+ EOF
13
+ }
14
+
15
+ log_info() { printf "[+] %s\n" "$*"; }
16
+ log_warn() { printf "[!] %s\n" "$*" >&2; }
17
+
18
+ if [[ $# -gt 0 ]]; then
19
+ case "${1:-}" in
20
+ --help|-h)
21
+ usage
22
+ exit 0
23
+ ;;
24
+ *)
25
+ echo "Opção desconhecida: $1" >&2
26
+ usage
27
+ exit 1
28
+ ;;
29
+ esac
30
+ fi
31
+
32
+ if [[ ! -t 0 ]]; then
33
+ echo "[ERRO] Terminal não interativo. Este comando exige confirmação dupla." >&2
34
+ exit 1
35
+ fi
36
+
37
+ declare -a MODEL_DIRS=()
38
+ tmp_models_file="$(mktemp "${TMPDIR:-/tmp}/rag-models.XXXXXX")"
39
+ cleanup_tmp_files() {
40
+ rm -f "${tmp_models_file}" "${tmp_models_sorted_file:-}" 2>/dev/null || true
41
+ }
42
+ trap cleanup_tmp_files EXIT
43
+
44
+ while IFS= read -r -d '' marker_file; do
45
+ model_dir="$(dirname "${marker_file}")"
46
+ printf '%s\n' "${model_dir}" >> "${tmp_models_file}"
47
+ done < <(find "${HOME}/.cache" -type f -name ".download_complete" -print0 2>/dev/null)
48
+
49
+ if [[ ! -s "${tmp_models_file}" ]]; then
50
+ log_info "Nenhum modelo encontrado para limpeza em ${HOME}/.cache."
51
+ exit 0
52
+ fi
53
+
54
+ tmp_models_sorted_file="$(mktemp "${TMPDIR:-/tmp}/rag-models-sorted.XXXXXX")"
55
+ LC_ALL=C sort -u "${tmp_models_file}" > "${tmp_models_sorted_file}"
56
+
57
+ while IFS= read -r model_path; do
58
+ [[ -z "${model_path}" ]] && continue
59
+ MODEL_DIRS+=("${model_path}")
60
+ done < "${tmp_models_sorted_file}"
61
+
62
+ echo "Modelos encontrados:"
63
+ for idx in "${!MODEL_DIRS[@]}"; do
64
+ printf " [%d] %s\n" "$((idx + 1))" "${MODEL_DIRS[$idx]}"
65
+ done
66
+ echo " [all] Remover todos os modelos listados"
67
+ echo ""
68
+
69
+ read -r -p "Escolha o número do modelo para remover ou 'all': " selection
70
+ selection="$(printf '%s' "${selection}" | tr '[:upper:]' '[:lower:]')"
71
+ selection="${selection#"${selection%%[![:space:]]*}"}"
72
+ selection="${selection%"${selection##*[![:space:]]}"}"
73
+
74
+ declare -a TARGETS=()
75
+ if [[ "${selection}" == "all" ]]; then
76
+ TARGETS=("${MODEL_DIRS[@]}")
77
+ elif [[ "${selection}" =~ ^[0-9]+$ ]]; then
78
+ selected_index=$((selection - 1))
79
+ if (( selected_index < 0 || selected_index >= ${#MODEL_DIRS[@]} )); then
80
+ log_warn "Seleção inválida."
81
+ exit 1
82
+ fi
83
+ TARGETS=("${MODEL_DIRS[$selected_index]}")
84
+ else
85
+ log_warn "Seleção inválida. Use um número da lista ou 'all'."
86
+ exit 1
87
+ fi
88
+
89
+ echo ""
90
+ echo "Alvos para remoção:"
91
+ for target in "${TARGETS[@]}"; do
92
+ echo " - ${target}"
93
+ done
94
+ echo ""
95
+
96
+ read -r -p "Confirma a remoção dos modelos selecionados? [s/N] " answer
97
+ answer="$(printf '%s' "${answer}" | tr '[:upper:]' '[:lower:]')"
98
+ if [[ "${answer}" != "s" && "${answer}" != "sim" && "${answer}" != "y" && "${answer}" != "yes" ]]; then
99
+ echo "Limpeza cancelada."
100
+ exit 0
101
+ fi
102
+
103
+ read -r -p "Digite LIMPAR para confirmar definitivamente: " confirm_word
104
+ if [[ "${confirm_word}" != "LIMPAR" ]]; then
105
+ echo "Confirmação inválida. Limpeza cancelada."
106
+ exit 1
107
+ fi
108
+
109
+ declare -a FAILED_PATHS=()
110
+ for target in "${TARGETS[@]}"; do
111
+ if [[ -e "${target}" || -L "${target}" ]]; then
112
+ if rm -rf "${target}" 2>/dev/null; then
113
+ log_info "Removido: ${target}"
114
+ else
115
+ FAILED_PATHS+=("${target}")
116
+ log_warn "Falha ao remover (permissão): ${target}"
117
+ fi
118
+ fi
119
+ done
120
+
121
+ if [[ ${#FAILED_PATHS[@]} -gt 0 ]]; then
122
+ echo ""
123
+ log_warn "Limpeza concluída com pendências:"
124
+ for failed_path in "${FAILED_PATHS[@]}"; do
125
+ echo " - ${failed_path}"
126
+ done
127
+ log_warn "Execute com sudo para limpar pendências, por exemplo:"
128
+ echo " sudo rm -rf ${FAILED_PATHS[0]}"
129
+ exit 1
130
+ fi
131
+
132
+ log_info "Limpeza de modelos concluída."
package/bin/rag-remove.sh CHANGED
@@ -8,7 +8,8 @@ Uso:
8
8
  rag remove --force
9
9
 
10
10
  Descrição:
11
- Remove toda a instalação local do own-rag (venv, banco, docker, binários e configuração MCP).
11
+ Remove a instalação local do own-rag (venv, banco, docker, binários e configuração MCP).
12
+ Modelos em cache NÃO são removidos por este comando.
12
13
 
13
14
  Opções:
14
15
  --force, -f pula a confirmação dupla.
@@ -96,15 +97,15 @@ declare -a REMOVE_PATHS=(
96
97
  "${HOME}/.rag_venv"
97
98
  "${HOME}/.rag_db"
98
99
  "${HOME}/docker-chromadb"
99
- "${HOME}/.cache/own-rag-cli"
100
- "${HOME}/.cache/my-custom-rag-python"
101
- "${HOME}/.cache/ny-custom-rag-python"
100
+ "${HOME}/.cache/own-rag-cli/logs"
101
+ "${HOME}/.cache/own-rag-cli/indexer_tuning.json"
102
102
  "${HOME}/.own-rag-cli.json"
103
103
  "${HOME}/.local/bin/mcp-rag-server"
104
104
  "${HOME}/.local/bin/download_model_from_hugginface.py"
105
105
  "${HOME}/.local/bin/download_model_from_modelscope.py"
106
106
  "${HOME}/.local/bin/rag-wrapper.sh"
107
107
  "${HOME}/.local/bin/rag-remove.sh"
108
+ "${HOME}/.local/bin/rag-clean-models.sh"
108
109
  "${HOME}/.local/bin/rag-setup.run"
109
110
  "${HOME}/.local/bin/rag-setup-macos.run"
110
111
  "${HOME}/.local/bin/chroma_monitor.sh"
@@ -231,3 +232,8 @@ if [[ ${#FAILED_PATHS[@]} -gt 0 ]]; then
231
232
  else
232
233
  log_info "Remoção completa concluída."
233
234
  fi
235
+
236
+ echo ""
237
+ log_info "Modelos baixados foram preservados no cache."
238
+ echo " Para apagar modelos não desejados, execute: rag clean models"
239
+ echo " O comando lista os modelos e permite escolher um específico ou 'all'."
@@ -11,6 +11,8 @@ LOCAL_MONITOR_SCRIPT="${LOCAL_BIN_DIR}/chroma_monitor.sh"
11
11
  PACKAGE_MONITOR_SCRIPT="${SCRIPT_DIR}/../chroma_monitor.sh"
12
12
  LOCAL_REMOVE_SCRIPT="${LOCAL_BIN_DIR}/rag-remove.sh"
13
13
  PACKAGE_REMOVE_SCRIPT="${SCRIPT_DIR}/../bin/rag-remove.sh"
14
+ LOCAL_CLEAN_MODELS_SCRIPT="${LOCAL_BIN_DIR}/rag-clean-models.sh"
15
+ PACKAGE_CLEAN_MODELS_SCRIPT="${SCRIPT_DIR}/../bin/rag-clean-models.sh"
14
16
 
15
17
  URL_TEMP_DIR=""
16
18
 
@@ -101,6 +103,28 @@ find_remove_runner() {
101
103
  return 1
102
104
  }
103
105
 
106
+ find_clean_models_runner() {
107
+ local os_name="$1"
108
+ if [[ "${os_name}" == "unknown" ]]; then
109
+ return 1
110
+ fi
111
+
112
+ if [[ -x "${LOCAL_CLEAN_MODELS_SCRIPT}" ]]; then
113
+ echo "${LOCAL_CLEAN_MODELS_SCRIPT}"
114
+ return 0
115
+ fi
116
+ if [[ -x "${PACKAGE_CLEAN_MODELS_SCRIPT}" ]]; then
117
+ echo "${PACKAGE_CLEAN_MODELS_SCRIPT}"
118
+ return 0
119
+ fi
120
+ if [[ -f "${PACKAGE_CLEAN_MODELS_SCRIPT}" ]]; then
121
+ chmod +x "${PACKAGE_CLEAN_MODELS_SCRIPT}" || true
122
+ echo "${PACKAGE_CLEAN_MODELS_SCRIPT}"
123
+ return 0
124
+ fi
125
+ return 1
126
+ }
127
+
104
128
  cleanup_url_temp_dir() {
105
129
  if [[ -n "${URL_TEMP_DIR}" && -d "${URL_TEMP_DIR}" ]]; then
106
130
  rm -rf "${URL_TEMP_DIR}" || true
@@ -235,6 +259,7 @@ Uso:
235
259
  rag run [path|url] [opcoes] --extensions ".js,.py,.md"
236
260
  rag monitor [command]
237
261
  rag remove
262
+ rag clean models
238
263
 
239
264
  Exemplos:
240
265
  rag run .
@@ -246,6 +271,7 @@ Exemplos:
246
271
  rag monitor
247
272
  rag monitor full
248
273
  rag remove
274
+ rag clean models
249
275
  EOF
250
276
  }
251
277
 
@@ -377,6 +403,25 @@ case "${command_name}" in
377
403
  fi
378
404
  exec "${remove_runner}" "$@"
379
405
  ;;
406
+ clean)
407
+ clean_target="${1:-}"
408
+ shift || true
409
+
410
+ case "${clean_target}" in
411
+ models)
412
+ if ! clean_models_runner="$(find_clean_models_runner "${os_name}")"; then
413
+ echo "Erro: rag-clean-models.sh não encontrado." >&2
414
+ echo "Esperado em: ${LOCAL_CLEAN_MODELS_SCRIPT} ou ${PACKAGE_CLEAN_MODELS_SCRIPT}" >&2
415
+ exit 1
416
+ fi
417
+ exec "${clean_models_runner}" "$@"
418
+ ;;
419
+ *)
420
+ echo "Erro: uso inválido. Use: rag clean models" >&2
421
+ exit 1
422
+ ;;
423
+ esac
424
+ ;;
380
425
  *)
381
426
  usage
382
427
  exit 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "own-rag-cli",
3
- "version": "0.0.11-snapshot",
3
+ "version": "0.0.13-snapshot",
4
4
  "description": "Local RAG setup with ChromaDB + MCP server (Jina/BGE hybrid support).",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -37,6 +37,7 @@
37
37
  "bin/requirements.txt",
38
38
  "bin/rag-wrapper.sh",
39
39
  "bin/rag-remove.sh",
40
+ "bin/rag-clean-models.sh",
40
41
  "bin/postinstall.sh",
41
42
  "bin/indexer_full.py",
42
43
  "bin/mcp_server.py",