Skip to content

fix(session-buffer): wire session_buffer_search into agent loop dispatch — closes #2667#3465

Open
Mibayy wants to merge 14 commits into
NousResearch:mainfrom
Mibayy:feat/session-context-buffer-2667
Open

fix(session-buffer): wire session_buffer_search into agent loop dispatch — closes #2667#3465
Mibayy wants to merge 14 commits into
NousResearch:mainfrom
Mibayy:feat/session-context-buffer-2667

Conversation

@Mibayy

@Mibayy Mibayy commented Mar 27, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the mid-session forgetfulness gap described in #2667.

The infrastructure for this feature was almost complete — compressed_buffer table with FTS5, SessionDB methods (archive_compressed_messages, search_compressed_buffer, get_compressed_buffer_count, clear_compressed_buffer), the session_buffer_search tool schema and registration, and the buffer population hook in _compress_context were all already merged. The missing piece was wiring session_buffer_search into the agent loop's special-case dispatch so it receives db and current_session_id.

Root Cause

session_buffer_search was falling through to handle_function_callregistry.dispatch(), which doesn't receive db or current_session_id as kwargs. Without those, every call returned {"success": false, "error": "Session database not available."} even when the DB was fully available.

Changes

run_agent.py — two dispatch sites, both now handle session_buffer_search:

  • _execute_tool_calls_sequential (sequential path) — new elif function_name == "session_buffer_search" block, mirroring the session_search pattern
  • _invoke_tool (concurrent/_execute_tool_calls_concurrent path) — same block

tests/tools/test_session_buffer_search.py (new, 36 tests):

  • TestArchiveCompressedMessages — skips system/empty/pruned, counts correctly
  • TestGetCompressedBufferCount — zero init, after archive, session scoping
  • TestSearchCompressedBuffer — FTS5 match, no match, session scoping, role filter, limit
  • TestClearCompressedBuffer — removes entries, doesn't affect other sessions
  • TestSessionBufferSearchTool — no-db error, no-session error, stats mode, search, parent-chain walk, limit cap, result fields
  • TestSessionBufferSearchSchema — schema name, description, required fields
  • TestResolveRootSessionId — root, child, grandchild, unknown session

How it works end-to-end

  1. On every context compression, _compress_context calls db.archive_compressed_messages(root_session_id, messages_being_dropped) — this was already wired
  2. Archived messages are indexed in compressed_buffer_fts (FTS5) via a trigger
  3. When the agent calls session_buffer_search("Tavily"), the new dispatch path injects db=self._session_db and current_session_id=self.session_id
  4. The tool resolves the root session ID (walking the parent_session_id chain) and runs an FTS5 query scoped to that root — finding content from any compression round of the current conversation
  5. Returns FTS5 snippets instantly, zero LLM cost

Closes #2667

Mibayy added 14 commits March 27, 2026 21:00
Adds three tools for querying a self-hosted OpenViking server:
- viking_search: semantic search over memories, resources, and skills
  (auto/fast/deep modes)
- viking_read: read content at a viking:// URI with configurable detail
  levels (abstract / overview / read)
- viking_browse: explore the OpenViking filesystem layout (tree/list/stat)

All tools are gated behind check_fn that verifies the server is reachable,
so they are silently absent when OpenViking is not running — same pattern as
Honcho. The 'openviking' named toolset is also added to TOOLSETS and to
the shared tools list so gateway and CLI pick them up automatically.

Configure via:
  OPENVIKING_ENDPOINT  (default: http://127.0.0.1:1933)
  OPENVIKING_API_KEY   (optional, for secured deployments)

Closes NousResearch#3368
/model was fully implemented in hermes_cli/model_switch.py and
hermes_cli/main.py but was never registered in COMMAND_REGISTRY,
causing it to be absent from /help output and Telegram bot commands.

Fixes NousResearch#3371
…ic cache, detailed trace, opt-in checkpointing
- delegate_dag: deque.popleft() replaces queue.pop(0) -- O(1) vs O(n)
- delegate_checkpoint: single persistent conn + threading.Lock, WAL mode
- delegate_tool: _CRITIC_MAX_SUMMARY_CHARS constant, critic toolsets=[],
  debug log on skill miss, key.replace('_',' ').title() for unknown keys,
  blackboard comment
- openviking_tool: try/except on r.json() in search and read paths
- Remove docs/plans/subagent-v2-*.md planning artifacts, gitignore them
…tch paths

The compressed_buffer table, FTS5 index, SessionDB methods, and tool schema
were all in place but session_buffer_search was never wired into the agent
loop's special-case dispatch (it fell through to handle_function_call which
lacks db/current_session_id context).

Changes:
- Add session_buffer_search special case to _execute_tool_calls_sequential
  (sequential path in run_agent.py) — mirrors the session_search pattern
- Add session_buffer_search special case to _invoke_tool (concurrent path)
- Add tests/tools/test_session_buffer_search.py — 36 tests covering
  archive_compressed_messages, search_compressed_buffer,
  get_compressed_buffer_count, clear_compressed_buffer, the tool function,
  schema validation, and parent-chain resolution

Closes NousResearch#2667
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder labels May 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Current-session context buffer — searchable archive of compressed messages

2 participants