hermes - ✅(Solved) Fix ACP list_sessions ignores cursor/cwd and never returns nextCursor [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#13450Fetched 2026-04-22 08:06:30
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
cross-referenced ×2closed ×1

HermesACPAgent.list_sessions() accepts cursor and cwd parameters but ignores both, and it always returns a ListSessionsResponse without nextCursor.

Root Cause

HermesACPAgent.list_sessions() accepts cursor and cwd parameters but ignores both, and it always returns a ListSessionsResponse without nextCursor.

Fix Action

Fixed

PR fix notes

PR #13460: fix: support pagination and cwd filtering in list sessions

Description (problem / solution / changelog)

Fixes Issue #13450. This commit adds cursor index tracking, limits, and nextCursor generation for the paginated ACP sessions list endpoint.

Changed files

  • acp_adapter/server.py (modified, +19/-1)

PR #13521: fix(acp): paginate list_sessions with cursor/next_cursor

Description (problem / solution / changelog)

Salvage of #13460 by @aniruddhaadak80 — closes #13450.

Summary

ACP list_sessions now respects cursor and returns next_cursor when more results remain. The page cap is a named module constant; cwd filtering (which already existed) is unchanged.

Changes

  • acp_adapter/server.py: cursor-based pagination, _LIST_SESSIONS_PAGE_SIZE = 50 module constant, docstring explaining cwd/cursor semantics. Unknown cursor returns an empty page (no fallback to full list).
  • tests/acp/test_server.py: 4 new tests — first-page w/ next_cursor, single-page no next_cursor, cursor resumes after match, unknown cursor returns empty.

Follow-ups on top of #13460

  • Replaced kwargs.get('limit', 50) with the module constant. ListSessionsRequest has no limit field in the ACP schema, so the kwarg path was dead.
  • Switched nextCursor= kwarg to the declared field name next_cursor= (the schema sets populate_by_name=True, so both work; field name is consistent with the rest of the file).

Validation

BeforeAfter
list_sessions(cursor=...)Cursor ignored, full list returnedPage resumes after cursor
ListSessionsResponse.next_cursorAlways NoneSet to last session_id when more remain
60 sessions, 2 cwdspage1=50 + next_cursor, page2=10, cwd filter=30, unknown cursor=[]
Tests2 list_sessions tests6 (all passing via scripts/run_tests.sh)

Changed files

  • acp_adapter/server.py (modified, +29/-1)
  • tests/acp/test_server.py (modified, +51/-0)

Code Example

async def list_sessions(self, cursor: str | None = None, cwd: str | None = None, ...)

---

infos = self.session_manager.list_sessions()
sessions = [SessionInfo(...)]
return ListSessionsResponse(sessions=sessions)

---

(*, nextCursor: Optional[str] = None, sessions: List[SessionInfo])

---

from pathlib import Path
import tempfile, threading, asyncio
from hermes_state import SessionDB
from acp_adapter.server import HermesACPAgent
from acp_adapter.session import SessionManager, SessionState

class DummyAgent: pass

with tempfile.TemporaryDirectory() as td:
    db = SessionDB(Path(td) / 'state.db')
    mgr = SessionManager(db=db)
    for sid, cwd in [('s1', '/a'), ('s2', '/b')]:
        mgr._sessions[sid] = SessionState(session_id=sid, agent=DummyAgent(), cwd=cwd, model='m', history=[], cancel_event=threading.Event())
        mgr.save_session(sid)
    agent = HermesACPAgent(session_manager=mgr)
    resp = asyncio.run(agent.list_sessions(cursor='s2', cwd='/a'))
    print([(s.session_id, s.cwd) for s in resp.sessions])
    print(getattr(resp, 'nextCursor', None))

---

[('s1', '/a'), ('s2', '/b')]
None
RAW_BUFFERClick to expand / collapse

Summary

HermesACPAgent.list_sessions() accepts cursor and cwd parameters but ignores both, and it always returns a ListSessionsResponse without nextCursor.

Affected files / lines

  • acp_adapter/server.py:337-348

Why this is a bug

The ACP handler signature explicitly exposes pagination/filter inputs:

async def list_sessions(self, cursor: str | None = None, cwd: str | None = None, ...)

But the implementation does:

infos = self.session_manager.list_sessions()
sessions = [SessionInfo(...)]
return ListSessionsResponse(sessions=sessions)

So callers cannot page results or request cwd-scoped session discovery.

The installed ACP schema also includes nextCursor on ListSessionsResponse:

(*, nextCursor: Optional[str] = None, sessions: List[SessionInfo])

Minimal reproduction

from pathlib import Path
import tempfile, threading, asyncio
from hermes_state import SessionDB
from acp_adapter.server import HermesACPAgent
from acp_adapter.session import SessionManager, SessionState

class DummyAgent: pass

with tempfile.TemporaryDirectory() as td:
    db = SessionDB(Path(td) / 'state.db')
    mgr = SessionManager(db=db)
    for sid, cwd in [('s1', '/a'), ('s2', '/b')]:
        mgr._sessions[sid] = SessionState(session_id=sid, agent=DummyAgent(), cwd=cwd, model='m', history=[], cancel_event=threading.Event())
        mgr.save_session(sid)
    agent = HermesACPAgent(session_manager=mgr)
    resp = asyncio.run(agent.list_sessions(cursor='s2', cwd='/a'))
    print([(s.session_id, s.cwd) for s in resp.sessions])
    print(getattr(resp, 'nextCursor', None))

Observed locally:

[('s1', '/a'), ('s2', '/b')]
None

Expected behavior

Either:

  • apply cwd filtering and cursor-based pagination, returning nextCursor when appropriate, or
  • reject unsupported params explicitly.

Actual behavior

The request shape suggests filtering/pagination support, but the server silently returns the full list.

Suggested investigation

Implement pagination/filter semantics in SessionManager.list_sessions() / ACP handler, or remove unsupported fields from the exposed behavior so clients do not rely on nonexistent filtering.

extent analysis

TL;DR

Implement pagination and filtering in SessionManager.list_sessions() to support cursor and cwd parameters and return nextCursor when necessary.

Guidance

  • Modify SessionManager.list_sessions() to accept and apply cursor and cwd filters to the session list.
  • Update HermesACPAgent.list_sessions() to pass cursor and cwd to SessionManager.list_sessions() and return nextCursor if pagination is applied.
  • Consider adding input validation to reject unsupported parameters if filtering and pagination are not implemented.
  • Review the ACP schema to ensure it aligns with the implemented behavior.

Example

class SessionManager:
    def list_sessions(self, cursor: str | None = None, cwd: str | None = None):
        # Apply filtering and pagination
        sessions = [session for session in self._sessions.values() if (cwd is None or session.cwd == cwd)]
        if cursor:
            sessions = [session for session in sessions if session.session_id > cursor]
        # Calculate nextCursor if pagination is applied
        next_cursor = None
        if sessions:
            next_cursor = sessions[-1].session_id
        return sessions, next_cursor

class HermesACPAgent:
    async def list_sessions(self, cursor: str | None = None, cwd: str | None = None):
        sessions, next_cursor = self.session_manager.list_sessions(cursor, cwd)
        return ListSessionsResponse(sessions=sessions, nextCursor=next_cursor)

Notes

The provided example is a simplified illustration and may require adjustments based on the actual implementation details of SessionManager and HermesACPAgent.

Recommendation

Apply workaround by implementing pagination and filtering in SessionManager.list_sessions() to align with the expected behavior and ACP schema.

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…

FAQ

Expected behavior

Either:

  • apply cwd filtering and cursor-based pagination, returning nextCursor when appropriate, or
  • reject unsupported params explicitly.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix ACP list_sessions ignores cursor/cwd and never returns nextCursor [2 pull requests, 1 participants]