Skip to content

Releases: svalench/django_graph_search

0.2.0

08 May 09:22
9b21ac9

Choose a tag to compare

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.x is 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) with BaseLLMBackend, RerankCandidate, deterministic DummyLLMBackend, 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 subclassing BaseMemoryBackend.
  • DELETE to clear a session, MAX_HISTORY_ITEMS / MIN_QUERY_LENGTH_FOR_AUTOSEARCH guardrails.

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 the build_search_index management 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 for fetch + ReadableStream and jq) and sse (for EventSource).
  • Runs the search in a worker thread; the request loop drains events through queue.Queue.
  • Terminal end event for reliable client-side stream termination.
  • Sets X-Accel-Buffering: no so 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 from 0.1.x is 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 above

Quality

  • 58 / 58 tests pass (8 original + 13 LangGraph + 16 conversational + 10 smart-indexing + 12 events/streaming).
  • python -m build produces wheel + sdist.
  • python -m twine check dist/* → PASSED for both artifacts.

Full changelog

See CHANGELOG.md.

Diff

v0.1.2...v0.2.0