Skip to content

Commit 43ba6de

Browse files
committed
session_search deepSearch: require 2+ distinct token matches
deepSearch was matching sessions where a single common word appeared anywhere in 100+ messages. Query 'go-vector changes' matched the events fetcher analysis session because 'changes' appeared once in a message — completely unrelated result. Now deepSearch tracks distinct matched tokens and requires at least 2. A single common word can no longer qualify a session. Also updated tool description to tell the LLM to use 'get' (after search) to read full session_messages content.
1 parent 12d4add commit 43ba6de

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

cmd/odek/session_search_tool.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ func newSessionSearchTool(store *session.Store) *sessionSearchTool {
2424
}
2525

2626
func (t *sessionSearchTool) Name() string { return "session_search" }
27-
func (t *sessionSearchTool) Description() string { return `Search and retrieve past agent sessions. Actions: list (recent sessions), search (semantic keyword search through full message content), get (full session by ID), find (sessions by task/title). Uses semantic vector search for the search action — it finds sessions whose conversation content is relevant to your query, even when titles don't match. Use OR between keywords for broad recall.` }
27+
func (t *sessionSearchTool) Description() string { return `Search and retrieve past agent sessions. Actions: list (recent sessions), search (semantic keyword search through full message content), get (full session by ID including ALL messages), find (sessions by task/title). Uses semantic vector search for the search action — it finds sessions whose conversation content is relevant to your query, even when titles don't match. Use OR between keywords for broad recall.
28+
29+
IMPORTANT: After search returns matching sessions, use get (not search) to read the actual conversation content. get returns the full session_messages array with every user and assistant message.` }
2830

2931
type sessionSearchArgs struct {
3032
Action string `json:"action"` // list, search, get, find
@@ -305,24 +307,35 @@ func (t *sessionSearchTool) deepSearch(tokens []string, candidates []session.Ses
305307
continue
306308
}
307309

308-
score := 0
310+
// Track which distinct query tokens matched across all messages.
311+
// This prevents a single common word like "changes" from qualifying
312+
// an unrelated 107-message session.
313+
matchedTokens := make(map[string]bool, len(tokens))
309314
var snippet string
310315
for _, msg := range full.Messages {
311316
if msg.Role != "user" && msg.Role != "assistant" {
312317
continue
313318
}
314-
if n := matchTokens(tokens, msg.Content); n > 0 {
315-
score += n
316-
if snippet == "" {
317-
snippet = truncate(msg.Content, 100)
319+
lower := strings.ToLower(msg.Content)
320+
for _, tok := range tokens {
321+
if len(tok) < 2 || matchedTokens[tok] {
322+
continue
323+
}
324+
if strings.Contains(lower, tok) {
325+
matchedTokens[tok] = true
326+
if snippet == "" {
327+
snippet = truncate(msg.Content, 100)
328+
}
318329
}
319330
}
320331
}
321332

322-
if score > 0 {
333+
// Require at least 2 distinct tokens to match (or all if query has only 1 token).
334+
// A single common word hitting one of 107 messages is noise, not signal.
335+
if len(matchedTokens) >= 2 || (len(tokens) == 1 && len(matchedTokens) == 1) {
323336
existing = append(existing, sessionMatch{
324337
session: *full,
325-
score: score,
338+
score: len(matchedTokens),
326339
snippet: snippet,
327340
})
328341
}

0 commit comments

Comments
 (0)