hermes - ✅(Solved) Fix Web session search can return fewer than limit unique sessions because it deduplicates after limiting message hits [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#14193Fetched 2026-04-23 07:46:15
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
labeled ×3cross-referenced ×2

GET /api/sessions/search passes the user limit directly to db.search_messages(...) and only after that deduplicates matches down to unique session_ids. If the first N message matches come from the same session, the endpoint can return far fewer than limit sessions even when more matching sessions exist.

Root Cause

GET /api/sessions/search passes the user limit directly to db.search_messages(...) and only after that deduplicates matches down to unique session_ids. If the first N message matches come from the same session, the endpoint can return far fewer than limit sessions even when more matching sessions exist.

Fix Action

Fixed

PR fix notes

PR #14208: fix(cli): return unique session search hits up to limit

Description (problem / solution / changelog)

Summary

Fix /api/sessions/search so the limit applies to unique sessions instead of raw message hits.

Before this change, the endpoint passed limit directly into search_messages(...) and only then deduplicated by session_id, so repeated hits from one session could crowd out other matching sessions.

Root cause

  • search_messages() paginates raw message matches.
  • /api/sessions/search deduplicated only after that pagination step.
  • The helper query ordered only by FTS rank, so batched LIMIT/OFFSET pagination was not stable when ranks tied.

Fix

  • Overfetch message matches in batches until the endpoint collects the requested number of unique sessions or exhausts the search results.
  • Make SessionDB.search_messages() pagination deterministic by ordering tied FTS ranks with m.id.

Regression coverage

Added a focused web-server regression that creates 25 identical matches in one session and 1 in another, then asserts limit=2 still returns both unique session IDs.

Testing

  • scripts/run_tests.sh tests/hermes_cli/test_web_server.py -k test_session_search_returns_limit_unique_sessions -v
  • scripts/run_tests.sh tests/hermes_cli/test_web_server.py -v
  • scripts/run_tests.sh tests/test_hermes_state.py -v

Closes #14193

Changed files

  • hermes_cli/web_server.py (modified, +25/-13)
  • hermes_state.py (modified, +1/-1)
  • tests/hermes_cli/test_web_server.py (modified, +19/-0)

PR #14265: fix(web): apply search limits to unique sessions

Description (problem / solution / changelog)

Summary

  • make /api/sessions/search overfetch message hits until it can return the requested number of unique sessions or exhaust the result set
  • keep the first snippet per session while preventing early duplicate hits from shrinking the API response below the requested limit
  • add a regression covering the case where the first fetched message hits all belong to the same session

Testing

  • python3 -m pytest -o addopts= tests/hermes_cli/test_web_server.py -k "session_search_overfetches_until_limit_unique_sessions"
  • python3 -m pytest -o addopts= tests/hermes_cli/test_web_server.py

Closes #14193

Changed files

  • hermes_cli/web_server.py (modified, +29/-13)
  • tests/hermes_cli/test_web_server.py (modified, +47/-0)
RAW_BUFFERClick to expand / collapse

Summary

GET /api/sessions/search passes the user limit directly to db.search_messages(...) and only after that deduplicates matches down to unique session_ids. If the first N message matches come from the same session, the endpoint can return far fewer than limit sessions even when more matching sessions exist.

Affected files

  • hermes_cli/web_server.py:398-412

Why this is a bug

Current flow:

  1. matches = db.search_messages(query=prefix_query, limit=limit)
  2. loop over matches
  3. keep only the first hit for each session_id

That means the endpoint limits messages, not sessions.

Minimal reproduction

Create matching content in multiple sessions:

  • session a: two messages containing needle
  • session b: one message containing needle

Then call the endpoint with limit=2.

Expected

Return up to 2 unique sessions, e.g. a and b.

Actual

db.search_messages(..., limit=2) can return two matches from session a; after dedupe, the endpoint returns only 1 session even though session b also matches.

Suggested investigation

Either:

  • overfetch message matches until limit unique sessions are collected, or
  • do session-level grouping/ranking in SQL so the API limit applies to unique sessions rather than raw message hits.

A regression test should build at least two matching sessions where one session has multiple early hits, then assert the endpoint still returns the requested number of unique sessions.

extent analysis

TL;DR

To fix the bug, modify the GET /api/sessions/search endpoint to either overfetch message matches until the desired number of unique sessions are collected or implement session-level grouping/ranking in SQL.

Guidance

  • Investigate modifying the db.search_messages call to return more matches than the requested limit to account for potential duplicates within sessions.
  • Consider implementing a session-level grouping or ranking mechanism in the SQL query to directly limit the number of unique sessions returned.
  • When testing the fix, ensure that the regression test covers scenarios where one session has multiple early hits to verify the endpoint returns the correct number of unique sessions.
  • Review the current deduplication logic to ensure it correctly handles the new approach to limiting sessions.

Example

# Example of overfetching message matches
matches = db.search_messages(query=prefix_query, limit=limit * 2)  # Overfetch to account for duplicates
unique_sessions = set()
for match in matches:
    if len(unique_sessions) < limit:
        unique_sessions.add(match.session_id)
    else:
        break

Notes

The choice between overfetching and implementing session-level grouping/ranking in SQL depends on the performance characteristics of the database and the typical distribution of matches across sessions.

Recommendation

Apply a workaround by overfetching message matches, as this approach is more straightforward to implement and test without requiring significant changes to the database query logic.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING