Fix transcript search snippet positioning (#6206)

This commit is contained in:
gloss-stack
2026-10-31 13:05:35 +00:00
committed by GitHub
parent bf5bf57bc1
commit 1d251ef867
2 changed files with 65 additions and 5 deletions
+23 -4
View File
@@ -67,15 +67,34 @@ def _snippet(content: str, query: str, radius: int = 60) -> str:
if not query: if not query:
return content[: radius * 2] return content[: radius * 2]
idx = content.lower().find(query.lower()) match_start = -1
if idx == -1: match_length = 0
lowered_content = content.lower()
for candidate in _query_terms(query):
idx = lowered_content.find(candidate.lower())
if idx != -1 and (match_start == -1 or idx < match_start):
match_start = idx
match_length = len(candidate)
if match_start == -1:
return content[: radius * 2] return content[: radius * 2]
start = max(0, idx - radius) start = max(0, match_start - radius)
end = min(len(content), idx + len(query) + radius) end = min(len(content), match_start + match_length + radius)
return ("..." if start > 0 else "") + content[start:end] + ("..." if end < len(content) else "") return ("..." if start > 0 else "") + content[start:end] + ("..." if end < len(content) else "")
def _query_terms(query: str) -> list[str]:
"""Return meaningful quoted phrases and tokens in user-entered order."""
terms: list[str] = []
for match in re.finditer(r'"([^"]+)"|[\w][\w._-]*', query, flags=re.UNICODE):
term = match.group(1) if match.group(1) is not None else match.group(0).strip("._-")
term = term.strip()
if term:
terms.append(term)
return terms
def _sanitize_fts_query(query: str) -> str | None: def _sanitize_fts_query(query: str) -> str | None:
"""Convert free text into a conservative FTS5 MATCH query. """Convert free text into a conservative FTS5 MATCH query.
+42 -1
View File
@@ -8,7 +8,7 @@ from sqlalchemy.orm import sessionmaker
from core.database import Base from core.database import Base
from core.database import ChatMessage as DbChatMessage from core.database import ChatMessage as DbChatMessage
from core.database import Session as DbSession from core.database import Session as DbSession
from src.session_search import SessionSearchResult, search_session_messages from src.session_search import SessionSearchResult, _snippet, search_session_messages
def _db(with_fts=True): def _db(with_fts=True):
@@ -61,6 +61,47 @@ def _has_fts(db):
) )
def test_snippet_locates_quoted_phrase_instead_of_raw_query():
content = "A" * 100 + "The session search result is useful." + "Z" * 100
snippet = _snippet(content, '"session search"', radius=20)
assert "session search" in snippet
assert snippet.startswith("...")
assert snippet.endswith("...")
def test_snippet_locates_punctuation_bearing_term_case_insensitively():
content = "A" * 100 + "Use FOO_BAR.py for routing." + "Z" * 100
snippet = _snippet(content, "foo_bar.py!", radius=20)
assert "FOO_BAR.py" in snippet
def test_snippet_uses_first_meaningful_matching_term():
content = "A" * 100 + "second appears here; first appears later." + "Z" * 100
snippet = _snippet(content, "first second", radius=12)
assert "second appears" in snippet
assert "first appears" not in snippet
def test_snippet_falls_back_to_content_start_when_no_term_matches():
content = "Beginning of the transcript, followed by more detail."
assert _snippet(content, '"missing phrase"', radius=10) == content[:20]
def test_snippet_preserves_boundary_markers_and_truncation():
content = "A" * 50 + "target" + "Z" * 50
snippet = _snippet(content, "target", radius=5)
assert snippet == "...AAAAAtargetZZZZZ..."
def test_session_search_uses_fts_and_returns_context(): def test_session_search_uses_fts_and_returns_context():
db = _db(with_fts=True) db = _db(with_fts=True)
try: try: