From 16360b967ac9273fec9934c297d4f982de26f952 Mon Sep 17 00:00:00 2001 From: Eugene&Monty <136487467+EugeneSukharev1988@users.noreply.github.com> Date: Sun, 19 Jul 2026 14:20:32 -0500 Subject: [PATCH] semantic resp structure - version --- README.md | 14 +++++++------- montycat/store_classes/kv.py | 8 +++++--- setup.py | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 2b5563a..a88063e 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ The official async Python client for [Montycat](https://montygovernance.com) — ```python # Search your data by MEANING — no external APIs, no separate vector database. # (already ON by default in the montycat-semantic server edition) -hits = await Sales.semantic_search_get_values("something to listen to music without wires", limit=5) -# → [{key, score, value: {"name": "Wireless Headphones"}}, ...] (matched by meaning, not keywords) +hits = await Sales.semantic_search_get_values("Show all Bluetooth devices", limit=5) +# → [{__key__, __score__, __value__: {"name": "Wireless Headphones"}}, ...] (matched by meaning, not keywords) ``` > ### 🧩 All-in-one. AI-native. **Zero external dependencies.** @@ -168,13 +168,13 @@ downloaded on demand, and every keyspace is embedded in the background as data i ```python # Semantic search is ON by default in the montycat-semantic edition — just search. # Rank stored items by meaning — two flavors: -# get_values → each hit is {key, score, value} -# get_keys → each hit is {key, score} (lighter; fetch a page later with get_bulk) -hits = await Sales.semantic_search_get_values("something to listen to music without wires", limit=5) -keys = await Sales.semantic_search_get_keys("something to listen to music without wires", limit=5) +# get_values → each hit is {__key__, __score__, __value__} +# get_keys → each hit is {__key__, __score__} (lighter; fetch a page later with get_bulk) +hits = await Sales.semantic_search_get_values("Show all Bluetooth devices", limit=5) +keys = await Sales.semantic_search_get_keys("Show all Bluetooth devices", limit=5) # Optionally drop weak matches by cosine similarity (range [-1, 1]). -strong = await Sales.semantic_search_get_keys("something to listen to music without wires", limit=5, min_score=0.35) +strong = await Sales.semantic_search_get_keys("Show all Bluetooth devices", limit=5, min_score=0.35) # Control the DB-wide switch (optional — it's already on): # switch the embedding model: 'minilm' | 'bge-small' (default) | 'bge-base' | 'e5-small' diff --git a/montycat/store_classes/kv.py b/montycat/store_classes/kv.py index 716100c..96102a3 100644 --- a/montycat/store_classes/kv.py +++ b/montycat/store_classes/kv.py @@ -405,7 +405,7 @@ async def semantic_search_get_keys(cls, query: str, limit: Union[int, list] = 0, below this value. Default None (no score filter). Returns: - list | str: A list of ranked hits, each `{'key': ..., 'score': ...}`. + list | str: A list of ranked hits, each `{'__key__': ..., '__score__': ...}`. Returns a string error message if the query fails. Raises: @@ -441,8 +441,10 @@ async def semantic_search_get_values(cls, query: str, limit: Union[int, list] = returned value. Default False. Returns: - list | str: A list of ranked hits, each `{'key': ..., 'score': ..., 'value': ...}`. - Returns a string error message if the query fails. + list | str: A list of ranked hits, each + `{'__key__': ..., '__score__': ..., '__value__': ...}` — the same + dunder envelope `lookup_values_where(key_included=True)` returns, + plus the score. Returns a string error message if the query fails. Raises: ValueError: If no query text is provided. diff --git a/setup.py b/setup.py index 8c876e7..a27b08f 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='montycat', - version='1.0.5', + version='1.0.6', description=( 'Self-hosted vector database + NoSQL with built-in AI semantic search — the async ' 'Python client for Montycat. A Rust-powered, AI-native Pinecone / Weaviate / Chroma '