Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/CONFIG_DRIFT.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This document tracks which environment/configuration knobs impact the indexing p
| --- | --- | --- | --- |
| `EMBEDDING_MODEL`, `EMBEDDING_PROVIDER` | Changes vector dimension/model space. | **Recreate** | Collection schema and stored vectors must match the embedding model; `ensure_collection()` recreates the collection when schema differs. |
| `REFRAG_MODE`, `QWEN3_EMBEDDING_ENABLED`, `MINI_VEC_DIM`, `LEX_SPARSE_MODE` | Adds/removes named vectors (mini, sparse) and advanced embedding paths. | **Recreate** | Qdrant cannot add/remove vector names in-place; we back up → delete → recreate the collection to apply these changes. |
| `INDEX_GRAPH_EDGES` | Enables/disables graph edge indexing for symbol relationships (defaults to enabled). | **Recreate** | Graph collections (`_graph` suffix) are created/deleted based on this setting; requires collection recreation. |
| `INDEX_SEMANTIC_CHUNKS`, `INDEX_CHUNK_LINES`, `INDEX_CHUNK_OVERLAP` | Alters semantic chunk sizes/overlaps. | **Reindex** | Requires reprocessing every file so chunks align with the new geometry. |
| `INDEX_MICRO_CHUNKS`, `MICRO_CHUNK_TOKENS`, `MICRO_CHUNK_STRIDE`, `MAX_MICRO_CHUNKS_PER_FILE` | Controls micro-chunk tier and token window. | **Reindex** | Points must be regenerated with the new token windows. |
| `USE_TREE_SITTER`, `INDEX_USE_ENHANCED_AST` | Enables AST-guided segmentation + smart reindex logic. | **Reindex** | Cached symbols and chunk boundaries change; files need reindexing to stay consistent. |
Expand Down
2 changes: 2 additions & 0 deletions scripts/admin_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def render_admin_acl(
deletion_enabled: bool = False,
work_dir: str = "/work",
refresh_ms: int = 5000,
flash: Optional[Dict[str, str]] = None,
status_code: int = 200,
) -> Any:
return _templates.TemplateResponse(
Expand All @@ -65,6 +66,7 @@ def render_admin_acl(
"work_dir": work_dir,
"staging_enabled": bool(is_staging_enabled() if callable(is_staging_enabled) else False),
"refresh_ms": int(refresh_ms) if refresh_ms is not None else 5000,
"flash": flash,
},
status_code=status_code,
)
Expand Down
37 changes: 34 additions & 3 deletions scripts/collection_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import re
import shutil
import time
import logging
from pathlib import Path
from datetime import datetime
from typing import Any, Dict, Optional, List
Expand All @@ -29,6 +30,14 @@
except Exception:
get_collection_mappings = None

try:
from scripts.ingest.graph_edges import get_graph_collection_name
except Exception:
get_graph_collection_name = None


logger = logging.getLogger(__name__)


_SLUGGED_REPO_RE = re.compile(r"^.+-[0-9a-f]{16}(?:_old)?$")
_MARKER_NAME = ".ctxce_managed_upload"
Expand Down Expand Up @@ -198,23 +207,45 @@ def delete_collection_everywhere(
"collection": name,
"qdrant_deleted": False,
"registry_marked_deleted": False,
"graph_collection_deleted": False,
"deleted_state_files": 0,
"deleted_managed_workspaces": 0,
}

target_is_old = name.endswith("_old")

# 1) Delete Qdrant collection
# 1) Delete Qdrant collection and its associated graph collection
try:
if pooled_qdrant_client is not None:
with pooled_qdrant_client(url=qdrant_url, api_key=os.environ.get("QDRANT_API_KEY")) as cli:
# Delete main collection
try:
cli.delete_collection(collection_name=name)
out["qdrant_deleted"] = True
except Exception:
except Exception as main_err:
out["qdrant_deleted"] = False
except Exception:
logger.warning("[collection_admin] Failed to delete collection %s: %s", name, main_err)
raise RuntimeError(f"Failed to delete collection {name}") from main_err

# Delete graph collection if it exists
if get_graph_collection_name is not None:
try:
graph_collection = get_graph_collection_name(name)
cli.delete_collection(collection_name=graph_collection)
out["graph_collection_deleted"] = True
except Exception as graph_err:
# Best-effort: graph collection might not exist
out["graph_collection_deleted"] = False
logger.warning(
"[collection_admin] Failed to delete graph collection %s (best-effort): %s",
name if "graph_collection" not in locals() else graph_collection,
graph_err,
)
except Exception as delete_exc:
logger.error("[collection_admin] Error deleting collections %s: %s", name, delete_exc)
out["qdrant_deleted"] = False
out["graph_collection_deleted"] = False
raise

# 2) Mark deleted in registry DB
try:
Expand Down
Loading
Loading