luplo.core.search

Search pipeline — glossary expansion → tsquery → optional vector rerank.

Submodules

Functions

search(→ list[luplo.core.models.SearchResult])

Run the full search pipeline.

Package Contents

async luplo.core.search.search(conn: psycopg.AsyncConnection[Any], query: str, project_id: str, *, embedding_backend: luplo.core.embedding.EmbeddingBackend | None = None, item_types: list[str] | None = None, system_ids: list[str] | None = None, limit: int = 10, tsquery: str | None = None) list[luplo.core.models.SearchResult]

Run the full search pipeline.

  1. Glossary expand"vendor""(vendor | shop | NPC벤더)".

  2. tsquery retrieval — GIN index scan, ts_rank scoring. Over-fetches limit * 3 candidates for reranking headroom.

  3. Vector rerank (optional) — if embedding_backend is provided and is not NullEmbedding, rerank candidates by cosine similarity. Otherwise return tsquery results as-is.

Parameters:
  • conn – Async psycopg connection.

  • query – Raw user query string (simple-dialect: word, “phrase”, OR, -negation). Glossary expanded. Ignored when tsquery is set.

  • project_id – Project scope.

  • embedding_backend – Embedding backend for reranking (default null).

  • item_types – Filter by item types (e.g. ["decision", "knowledge"]).

  • system_ids – Filter by system membership.

  • limit – Maximum results to return.

  • tsquery – Optional escape hatch — a raw PostgreSQL to_tsquery expression (e.g. "(inventory | 인벤토리) & slot & !deprecated"). When set, query and glossary expansion are bypassed and the string is passed directly to to_tsquery('simple', …). Caller is responsible for synonym coverage and valid syntax. A malformed expression raises InvalidTsquery.

Returns:

Ranked list of SearchResult objects.