feat(vector): server-side kinds filter for search_similar (legacy fallback) + graceful solved-search degrade
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -516,12 +516,26 @@ def solved_search_cmd(
|
||||
|
||||
from tht.cli.vector_cmd import make_embedder, open_searcher
|
||||
from tht.solved import SOLVED_KIND
|
||||
from tht.vectorstore.embeddings import EmbeddingsError
|
||||
from tht.vectorstore.rest_client import VectorRestError
|
||||
|
||||
cfg = _load_config_or_exit(config)
|
||||
require_vector_cfg(cfg)
|
||||
searcher = open_searcher(cfg)
|
||||
embedder = make_embedder(cfg.embeddings)
|
||||
hits = searcher.search(embedder.embed_query(question), top_n=top, kinds=[SOLVED_KIND])
|
||||
# Degrado gentile: SKILL.md prescrive solved-search in F4/F6/F7 di ogni sessione,
|
||||
# quindi vectordb/Ollama irraggiungibili non devono produrre un traceback grezzo
|
||||
# nel transcript: avviso di una riga su stderr, stdout puro ([] in --json), exit 0.
|
||||
try:
|
||||
searcher = open_searcher(cfg)
|
||||
embedder = make_embedder(cfg.embeddings)
|
||||
hits = searcher.search(embedder.embed_query(question), top_n=top, kinds=[SOLVED_KIND])
|
||||
except (VectorRestError, EmbeddingsError, OperationalError) as e:
|
||||
typer.secho(
|
||||
f"ATTENZIONE: exemplar non disponibili ({e}). Prosegui senza.",
|
||||
fg=typer.colors.YELLOW, err=True,
|
||||
)
|
||||
if json_out:
|
||||
typer.echo("[]")
|
||||
return
|
||||
results = [
|
||||
{
|
||||
"session_id": h.metadata.get("session_id", h.ref),
|
||||
|
||||
@@ -45,10 +45,11 @@ class RestSearcher:
|
||||
) -> list[VectorHit]:
|
||||
hits: list[VectorHit] = []
|
||||
for table in tables_for_kinds(kinds):
|
||||
for row in self.client.search_similar(table, query_vec, top_n):
|
||||
for row in self.client.search_similar(table, query_vec, top_n, kinds=kinds):
|
||||
hits.append(hit_from_metadata(row.get("similarity", 0.0), row.get("metadata")))
|
||||
# schema_records contiene sia schema_table sia schema_column: la RPC non filtra
|
||||
# per kind, quindi lo facciamo lato client per parita' col path diretto (#25).
|
||||
# Il filtro per kind avviene server-side (RPC con `kinds`); il post-filter resta
|
||||
# come difesa per il fallback legacy (server pre-migrazione: 404 -> query senza
|
||||
# filtro) e per parita' col path diretto (#25).
|
||||
if kinds:
|
||||
allowed = set(kinds)
|
||||
hits = [h for h in hits if h.kind in allowed]
|
||||
|
||||
@@ -58,18 +58,28 @@ class VectorRestClient:
|
||||
return resp.json()
|
||||
|
||||
def search_similar(
|
||||
self, table_name: str, query_embedding: list[float], limit_count: int
|
||||
self, table_name: str, query_embedding: list[float], limit_count: int,
|
||||
kinds: list[str] | None = None,
|
||||
) -> list[dict]:
|
||||
"""Ricerca per similarità coseno su `vectors.<table_name>`: ritorna le righe
|
||||
`{id, similarity, metadata}` ordinate per similarity decrescente."""
|
||||
return self._call(
|
||||
"search_similar",
|
||||
{
|
||||
"query_embedding": query_embedding,
|
||||
"limit_count": limit_count,
|
||||
"table_name": table_name,
|
||||
},
|
||||
) or []
|
||||
`{id, similarity, metadata}` ordinate per similarity decrescente. Con `kinds`
|
||||
il filtro avviene server-side nel WHERE della RPC (evita la diluizione del
|
||||
top-k quando piu' kind condividono la tabella, es. memory/solved_question).
|
||||
Su un server legacy senza il parametro (PostgREST 404) ritenta senza filtro:
|
||||
resta il post-filter client-side di RestSearcher."""
|
||||
args = {
|
||||
"query_embedding": query_embedding,
|
||||
"limit_count": limit_count,
|
||||
"table_name": table_name,
|
||||
}
|
||||
if kinds is not None:
|
||||
try:
|
||||
return self._call("search_similar", {**args, "kinds": kinds}) or []
|
||||
except VectorRestError as e:
|
||||
if "HTTP 404" not in str(e):
|
||||
raise
|
||||
# funzione a 3 argomenti (pre-migrazione kinds): fallback senza filtro
|
||||
return self._call("search_similar", args) or []
|
||||
|
||||
def list_tables(self) -> list[dict]:
|
||||
"""Tabelle vettoriali disponibili: `{table_name, vector_dimensions, …}`."""
|
||||
|
||||
Reference in New Issue
Block a user