Releases: svalench/django_graph_search
0.2.0
django-graph-search v0.2.0 — LangGraph integration
TL;DR. Optional LangGraph orchestration layer with query expansion, reranking, conversational search, smart indexing and streaming responses. Every new feature is off by default — upgrading from
0.1.xis a no-op behaviourally.
Highlights
LangGraph search pipeline (LANGGRAPH.ENABLED)
A 5-node graph — analyze_query → expand_query → vector_search → rerank_results → postprocess_results — sits behind the existing Searcher.search API. Works with or without the langgraph package: when it is missing, an in-tree fallback runner mirrors the same conditional structure so behaviour stays identical.
- Per-feature toggles:
QUERY_EXPANSION,RERANKING,MAX_EXPANDED_QUERIES,RERANK_TOP_K,MAX_QUERY_LENGTH. - LLM abstraction (
llm/subpackage) withBaseLLMBackend,RerankCandidate, deterministicDummyLLMBackend, dotted-path factory. - LLM errors never poison search — every node degrades to its deterministic baseline and surfaces failures in
state["errors"].
Conversational search (CONVERSATIONAL.ENABLED)
New POST /api/search/conversation/ endpoint with session memory and follow-up handling.
- 5-node graph:
load_context → interpret_followup → maybe_clarify → execute_search → store_context. - Deterministic regex handling for "more / similar / filter X" patterns — works without an LLM.
- Pluggable memory backends:
inmemory,cache/redis(DjangoCacheBackend), or bring your own by subclassingBaseMemoryBackend. DELETEto clear a session,MAX_HISTORY_ITEMS/MIN_QUERY_LENGTH_FOR_AUTOSEARCHguardrails.
Smart indexing (SMART_INDEXING.ENABLED)
SmartIndexer builds structured documents with labelled sections (Title:, Description:, Category: …) so the embedder can distinguish field roles instead of seeing a flat token soup.
- Per-model
TEMPLATES, with a deterministic heuristic fallback when none is registered. - New
get_indexer()factory transparently routes signals,index(), and thebuild_search_indexmanagement command. - Always appends the legacy whitespace-joined text as a safety net — smart indexing never produces less searchable content than the classic indexer.
Streaming search (STREAMING.ENABLED)
StreamingSearchAPIView at /api/search/stream/ streams pipeline lifecycle events to the client as they happen.
- Two transports:
ndjson(default, perfect forfetch+ReadableStreamandjq) andsse(forEventSource). - Runs the search in a worker thread; the request loop drains events through
queue.Queue. - Terminal
endevent for reliable client-side stream termination. - Sets
X-Accel-Buffering: noso reverse proxies don't buffer the response.
$ curl -N "http://localhost:8000/api/search/stream/?q=phone"
{"type": "query_received", "query": "phone"}
{"type": "vector_search_completed", "candidate_count": 12}
{"type": "completed", "total": 5}
{"type": "results", "results": [...], "total": 5}
{"type": "end"}Backwards compatibility
- Every new flag defaults to
False. Upgrading from0.1.xis behaviourally a no-op. - Public API (
Searcher,Indexer, REST endpoints, signals) is preserved. - Re-indexing is not required to switch smart indexing on or off.
- No new mandatory dependencies —
langgraph, LLM SDKs, and Redis remain entirely optional.
Install
pip install --upgrade django-graph-search
# Optional extras
pip install "django-graph-search[langgraph]" # LangGraph orchestration
pip install "django-graph-search[chromadb]" # Chroma vector store
pip install "django-graph-search[faiss]" # FAISS vector store
pip install "django-graph-search[qdrant]" # Qdrant vector store
pip install "django-graph-search[all]" # Everything aboveQuality
- 58 / 58 tests pass (8 original + 13 LangGraph + 16 conversational + 10 smart-indexing + 12 events/streaming).
python -m buildproduces wheel + sdist.python -m twine check dist/*→ PASSED for both artifacts.
Full changelog
See CHANGELOG.md.