Skip to content

fix(hindsight): correct client constructor, add configurable base_url, and fix sequential tool dispatch#4762

Closed
nils010485 wants to merge 2 commits into
NousResearch:mainfrom
nils010485:fix/hindsight-client-constructor
Closed

fix(hindsight): correct client constructor, add configurable base_url, and fix sequential tool dispatch#4762
nils010485 wants to merge 2 commits into
NousResearch:mainfrom
nils010485:fix/hindsight-client-constructor

Conversation

@nils010485

@nils010485 nils010485 commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Two related fixes for the Hindsight memory plugin.

Fix 1: incorrect constructor arguments (broken in cloud mode)

_make_client() passed api_key as the first positional argument to Hindsight(), but the constructor expects base_url first. The plugin never worked in cloud mode.

# Before (broken)
return Hindsight(api_key=*** timeout=30.0)

# After (fixed)
return Hindsight(base_url=base_url, api_key=*** timeout=120.0)

Also adds configurable api_url for self-hosted Docker instances (config, env var, setup wizard).

Fix 2: memory tools not dispatched in sequential path

Memory provider tools (hindsight_retain/recall/reflect) were only dispatched in the concurrent tool call path (_invoke_tool). The sequential path (_execute_tool_calls_sequential) fell through to handle_function_call() which returned "Unknown tool" — so the tools only worked when multiple tools were called concurrently.

Changes

plugins/memory/hindsight/__init__.py

  • _load_config(): add api_url from HINDSIGHT_API_URL env var
  • get_config_schema(): add api_url field with env var hint
  • _make_client(): resolve base_url from config → env → default; pass as first arg; timeout 120s

run_agent.py

  • _execute_tool_calls_sequential(): add memory_manager.has_tool() guard matching the concurrent path

Pre-existing code referenced in this PR

These are not introduced by this PR — they already exist on main:

  • _DEFAULT_API_URLplugins/memory/hindsight/__init__.py:32
  • has_tool()agent/memory_manager.py:207
  • handle_tool_call()agent/memory_manager.py:211 (dispatcher, implemented by every memory plugin)

Verifiable on main:

gh api 'repos/NousResearch/hermes-agent/contents/plugins/memory/hindsight/__init__.py?ref=main' -q '.content' | base64 -d | grep -n _DEFAULT_API_URL
# Output: 32:_DEFAULT_API_URL = "https://api.hindsight.vectorize.io"

gh api 'repos/NousResearch/hermes-agent/contents/agent/memory_manager.py?ref=main' -q '.content' | base64 -d | grep -nE 'def has_tool|def handle_tool_call'
# Output:
# 207:    def has_tool(self, tool_name: str) -> bool:
# 211:    def handle_tool_call(

Testing

  • ✅ Tested locally with self-hosted Docker Hindsight (localhost:8888)
  • ✅ Pipeline works: retainrecallreflect all functional
  • ✅ Sequential and concurrent tool dispatch both work
  • ✅ No existing tests broken (Hindsight tests use FakeMemoryProvider)

…able base_url

The Hindsight cloud-mode client was broken: _make_client() passed api_key
as the first positional argument to Hindsight(), but the constructor
expects base_url first. This meant the plugin never worked in cloud mode.

Additionally, add support for self-hosted Hindsight instances by:
- Reading api_url from config.json (HINDSIGHT_API_URL env var)
- Adding api_url to get_config_schema() for hermes setup wizard
- Falling back to _DEFAULT_API_URL when no custom URL is set
- Increasing timeout from 30s to 120s (Hindsight extraction can be slow)
@nils010485 nils010485 marked this pull request as draft April 3, 2026 10:47
Memory provider tools (e.g. hindsight_retain/recall/reflect) were only
dispatched in the concurrent path (_invoke_tool) but not in the sequential
path (_execute_tool_calls_sequential). All sequential calls fell through
to handle_function_call() which returned 'Unknown tool'.

Add the same memory_manager.has_tool() guard in the sequential path,
matching the pattern used in the concurrent path.
@nils010485 nils010485 changed the title fix(hindsight): correct client constructor and add configurable base_url fix(hindsight): correct client constructor, add configurable base_url, and fix sequential tool dispatch Apr 3, 2026
@nils010485 nils010485 marked this pull request as ready for review April 3, 2026 10:54
@britrik

britrik commented Apr 3, 2026

Copy link
Copy Markdown

Code Review

Fix 1: Hindsight Client Constructor

The fix correctly addresses the broken cloud mode. The constructor was passing api_key as the first positional argument when Hindsight expects base_url first.

Changes look good:

  • Added api_url to config loading from HINDSIGHT_API_URL env var
  • Added api_url to config schema with proper description and env var hint
  • Modified _make_client() to resolve base_url from config to env to default
  • Passes base_url as first argument with named parameter (safer)
  • Increased timeout from 30s to 120s (reasonable for API calls)

Note: The diff references _DEFAULT_API_URL but I dont see it defined in the repository. Please verify this constant exists or should be defined.

Fix 2: Sequential Tool Dispatch

The fix correctly adds memory tool handling to the sequential path. The memory tools were only being dispatched in the concurrent path, causing them to return Unknown tool in sequential mode.

Changes look good:

  • Added check for memory_manager.has_tool(function_name) before falling through to handle_function_call()
  • Properly handles the tool result and timing

Note: Please verify that has_tool() and handle_tool_call() methods exist on the memory manager interface. I could not find these methods in the current codebase - they may need to be added or may already exist in a different location.

Overall

Both fixes address real bugs that would prevent the Hindsight memory plugin from working properly. The changes are minimal and focused.

Approve pending verification of _DEFAULT_API_URL constant and memory manager methods.

@nils010485

nils010485 commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

Note: The diff references _DEFAULT_API_URL but I don't see it defined in the repository. Please verify this constant exists or should be defined.

This constant already exists on main — it was not added by this PR:

# plugins/memory/hindsight/__init__.py:32
_DEFAULT_API_URL = "https://api.hindsight.vectorize.io"

The diff context was likely truncated by GitHub since the file is large. You can verify directly on main (note: URL needs quoting in zsh):

gh api 'repos/NousResearch/hermes-agent/contents/plugins/memory/hindsight/__init__.py?ref=main' -q '.content' | base64 -d | grep -n '_DEFAULT_API_URL'
# Output: 32:_DEFAULT_API_URL = "https://api.hindsight.vectorize.io"

Note: Please verify that has_tool() and handle_tool_call() methods exist on the memory manager interface. I could not find these methods in the current codebase.

Both methods already exist on main — neither was added by this PR:

  • has_tool()agent/memory_manager.py:207
  • handle_tool_call()agent/memory_manager.py:211 (dispatcher), implemented by every memory plugin (hindsight, retaindb, mem0, openviking, holographic, honcho, byterover)

You can verify:

gh api 'repos/NousResearch/hermes-agent/contents/agent/memory_manager.py?ref=main' -q '.content' | base64 -d | grep -n 'def has_tool\|def handle_tool_call'
# Output:
# 207:    def has_tool(self, tool_name: str) -> bool:
# 211:    def handle_tool_call(

Both notes are false positives — the referenced code is part of the existing codebase, not introduced by this PR.

@britrik

britrik commented Apr 3, 2026

Copy link
Copy Markdown

Code Review ✅

Summary: Two related fixes for the Hindsight memory plugin - both look correct.

Fix 1: Client constructor arguments

  • Problem: passed as first positional arg, but constructor expects first
  • Fix: Now correctly passes with proper fallback chain (config → env → default)
  • Bonus: Adds configurable for self-hosted Docker instances via env var
  • Timeout: Increased from 30s to 120s - reasonable for API calls

Fix 2: Sequential tool dispatch

  • Problem: Memory tools only worked in concurrent path; sequential path fell through to which returned "Unknown tool"
  • Fix: Added check in to route to memory provider before generic dispatch
  • Pattern: Matches how other agent-level tools (todo, memory, session_search) are handled in

Quality Notes

  • Config schema properly includes hint for the new field
  • Base URL resolution uses clean fallback chain: → →
  • Display logic in sequential path matches concurrent path pattern

LGTM - ship it! 🚀

@britrik

britrik commented Apr 3, 2026

Copy link
Copy Markdown

Code Review

Fix 1: Hindsight Client Constructor ✅

The fix correctly addresses the broken cloud mode. The constructor was passing as the first positional argument when expects first.

Changes look good:

  • Added to config loading from env var
  • Added to config schema with proper description and env var hint
  • Modified to resolve from config → env → default
  • Passes as first argument with named parameter (safer)
  • Increased timeout from 30s to 120s (reasonable for API calls)

One note: The diff references but I don't see it defined in the repository. Please verify this constant exists or should be defined (e.g., ).

Fix 2: Sequential Tool Dispatch ✅

The fix correctly adds memory tool handling to the sequential path. The memory tools were only being dispatched in the concurrent path (), causing them to return "Unknown tool" in sequential mode.

Changes look good:

  • Added check for before falling through to
  • Properly handles the tool result and timing

One note: Please verify that and methods exist on the memory manager interface. I couldn't find these methods in the current codebase - they may need to be added or may already exist in a different location.

Overall

Both fixes address real bugs that would prevent the Hindsight memory plugin from working properly. The changes are minimal and focused.

✅ Approve pending verification of constant and memory manager methods.

@nils010485

nils010485 commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

One note: The diff references _DEFAULT_API_URL but I don't see it defined in the repository.

This constant already exists on main — it was not added by this PR:

# plugins/memory/hindsight/__init__.py:32
_DEFAULT_API_URL = "https://api.hindsight.vectorize.io"

You can verify directly:

gh api 'repos/NousResearch/hermes-agent/contents/plugins/memory/hindsight/__init__.py?ref=main' -q '.content' | base64 -d | grep -n _DEFAULT_API_URL
# Output: 32:_DEFAULT_API_URL = "https://api.hindsight.vectorize.io"

One note: Please verify that has_tool() and handle_tool_call() methods exist on the memory manager interface.

Both methods already exist on main — neither was added by this PR:

  • has_tool()agent/memory_manager.py:207
  • handle_tool_call()agent/memory_manager.py:211 (dispatcher), implemented by every memory plugin (hindsight, retaindb, mem0, openviking, holographic, honcho, byterover)

You can verify:

gh api 'repos/NousResearch/hermes-agent/contents/agent/memory_manager.py?ref=main' -q '.content' | base64 -d | grep -nE 'def has_tool|def handle_tool_call'
# Output:
# 207:    def has_tool(self, tool_name: str) -> bool:
# 211:    def handle_tool_call(

Both notes are false positives — the referenced code is part of the existing codebase, not introduced by this PR. I've also updated the PR description with a "Pre-existing code" section and verified commands.

@teknium1

teknium1 commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

Already fixed on main via PR #4803 (merged). The memory provider dispatch block in _execute_tool_calls_sequential is identical to this fix. Thanks for catching the same issue!

@teknium1 teknium1 closed this Apr 4, 2026
nils010485 pushed a commit to nils010485/hermes-agent that referenced this pull request Apr 4, 2026
…api_url

The Hindsight() constructor expects base_url as the first positional
argument, but _make_client() passed api_key in that position. This made
cloud mode completely non-functional.

Also adds configurable api_url (via config, HINDSIGHT_API_URL env var,
or setup wizard) so self-hosted Docker instances can be used instead of
the default cloud endpoint. Timeout increased from 30s to 120s.

Fixes the remaining issue from PR NousResearch#4762 (sequential dispatch was
already fixed by PR NousResearch#4803).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants