v0.17.3: bug-fix maintenance pass — ingest origin exemption, FK safety, auto-search reset, deterministic ingest, WAL, config centralization, dead-code removal

- /api/ingest exempt from origin check for CLI/Bearer clients
- recreate deleted conversations on bogus conversation_id (chat + search)
- augmented auto-search emits reset:true; frontend clears first-pass text
- image uploads stored as placeholders, never text-ingested
- check_fact_conflicts requires shared subject keywords
- deterministic ingest point ids (md5 chunk hash)
- get_load() no longer crashes when rocm-smi yields no VRAM lines
- SQLite WAL + busy_timeout; timing-safe API key compares
- supervise fire-and-forget auto-ingest tasks; log missing logprobs
- centralize EMBED_URL/EMBED_MODEL/QDRANT_URL/NODE_NAME in config
- remove dead triage.py, select_node tests, is_state_changing, stray artifacts
- add regression tests + autouse global-reset conftest
This commit is contained in:
gramps
2026-08-07 14:42:35 -07:00
parent df405a156e
commit 44387919a8
24 changed files with 478 additions and 7171 deletions
+20 -1
View File
@@ -38,6 +38,21 @@ AUTO_FACT_PATTERNS = [
]
SOCIAL_TRIGGERS = {"hi", "hello", "hey", "yo", "sup", "howdy", "good morning", "good evening"}
# Short filler words that shouldn't count as subject overlap between facts.
_STOPWORDS = {
"with", "that", "have", "this", "from", "they", "what", "when", "where",
"which", "there", "your", "will", "would", "about", "these", "their",
"been", "into", "than", "then", "them", "were", "being", "more", "most",
"some", "other", "only", "still", "also", "after", "before", "during",
"because", "through", "without",
}
def _subject_words(text: str) -> set:
"""Meaningful subject tokens for overlap comparison."""
words = re.findall(r"[A-Za-z0-9_]{4,}", text.lower())
return {w for w in words if w not in _STOPWORDS}
def _is_social(text: str) -> bool:
t = text.strip().lower()
@@ -86,6 +101,10 @@ def auto_detect_facts(user_message: str, assistant_message: str) -> list[str]:
def check_fact_conflicts(facts: list[str]) -> list[dict]:
"""Search for existing memories that conflict with detected facts.
A conflict is reported only when the existing memory is about the same
subject (meaningful keyword overlap) but states something different —
unrelated hits that merely share an FTS keyword are not conflicts.
Returns list of {memory_id, old_fact, new_fact} for each conflict.
"""
conflicts = []
@@ -93,7 +112,7 @@ def check_fact_conflicts(facts: list[str]) -> list[dict]:
related = search_memories(new_fact, limit=1)
if related:
old = related[0]["fact"]
if old.rstrip(".") != new_fact.rstrip("."):
if old.rstrip(".") != new_fact.rstrip(".") and (_subject_words(new_fact) & _subject_words(old)):
conflicts.append({
"memory_id": related[0]["rowid"],
"old_fact": old,