mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-01 12:02:05 +00:00
feat(dashboard): catalogue all memory-provider API keys in OPTIONAL_ENV_VARS
The dashboard Keys page and `hermes setup` render API-key rows from OPTIONAL_ENV_VARS, but only Honcho had an entry — so Hindsight, Supermemory, Mem0, RetainDB, ByteRover, and OpenViking read their keys straight from os.environ yet had no place to set them in the GUI. Add catalog entries (category=tool, password-masked, with get-key URLs and the tool each powers) for all six, plus the relevant base-URL/endpoint companions. Pure declaration: the generic GET /api/env endpoint, the save/reveal write path, and the sandbox env blocklist (which auto-derives from tool-category OPTIONAL_ENV_VARS) all pick these up with no further wiring. Adds a behavior-contract test asserting every memory provider's primary credential key is catalogued, tool-categorised, and password-masked.
This commit is contained in:
parent
c8fd47be14
commit
dee41d0716
2 changed files with 120 additions and 0 deletions
|
|
@ -3649,6 +3649,83 @@ OPTIONAL_ENV_VARS = {
|
|||
"category": "tool",
|
||||
},
|
||||
|
||||
# ── Hindsight ──
|
||||
"HINDSIGHT_API_KEY": {
|
||||
"description": "Hindsight API key for graph-aware persistent memory",
|
||||
"prompt": "Hindsight API key",
|
||||
"url": "https://hindsight.vectorize.io",
|
||||
"tools": ["hindsight_recall"],
|
||||
"password": True,
|
||||
"category": "tool",
|
||||
},
|
||||
"HINDSIGHT_API_URL": {
|
||||
"description": "Base URL for the Hindsight API (default: https://api.hindsight.vectorize.io)",
|
||||
"prompt": "Hindsight API URL",
|
||||
"category": "tool",
|
||||
"advanced": True,
|
||||
},
|
||||
|
||||
# ── Supermemory ──
|
||||
"SUPERMEMORY_API_KEY": {
|
||||
"description": "Supermemory API key for conversation-scoped persistent memory",
|
||||
"prompt": "Supermemory API key",
|
||||
"url": "https://supermemory.ai",
|
||||
"tools": ["supermemory_search"],
|
||||
"password": True,
|
||||
"category": "tool",
|
||||
},
|
||||
|
||||
# ── Mem0 ──
|
||||
"MEM0_API_KEY": {
|
||||
"description": "Mem0 Platform API key for semantic persistent memory",
|
||||
"prompt": "Mem0 API key",
|
||||
"url": "https://app.mem0.ai",
|
||||
"tools": ["mem0_search"],
|
||||
"password": True,
|
||||
"category": "tool",
|
||||
},
|
||||
|
||||
# ── RetainDB ──
|
||||
"RETAINDB_API_KEY": {
|
||||
"description": "RetainDB API key for persistent memory",
|
||||
"prompt": "RetainDB API key",
|
||||
"url": "https://retaindb.com",
|
||||
"tools": ["retaindb_search"],
|
||||
"password": True,
|
||||
"category": "tool",
|
||||
},
|
||||
"RETAINDB_BASE_URL": {
|
||||
"description": "Base URL for self-hosted RetainDB instances (default: https://api.retaindb.com)",
|
||||
"prompt": "RetainDB base URL",
|
||||
"category": "tool",
|
||||
"advanced": True,
|
||||
},
|
||||
|
||||
# ── ByteRover ──
|
||||
"BRV_API_KEY": {
|
||||
"description": "ByteRover API key (optional, for cloud sync — local-first by default)",
|
||||
"prompt": "ByteRover API key",
|
||||
"url": "https://app.byterover.dev",
|
||||
"tools": ["brv_query"],
|
||||
"password": True,
|
||||
"category": "tool",
|
||||
},
|
||||
|
||||
# ── OpenViking ──
|
||||
"OPENVIKING_API_KEY": {
|
||||
"description": "OpenViking API key (leave blank for local dev mode)",
|
||||
"prompt": "OpenViking API key",
|
||||
"tools": ["viking_search"],
|
||||
"password": True,
|
||||
"category": "tool",
|
||||
},
|
||||
"OPENVIKING_ENDPOINT": {
|
||||
"description": "OpenViking server URL (default: http://127.0.0.1:1933)",
|
||||
"prompt": "OpenViking endpoint",
|
||||
"category": "tool",
|
||||
"advanced": True,
|
||||
},
|
||||
|
||||
# ── Langfuse observability ──
|
||||
"HERMES_LANGFUSE_PUBLIC_KEY": {
|
||||
"description": "Langfuse project public key (pk-lf-...)",
|
||||
|
|
|
|||
|
|
@ -700,6 +700,49 @@ class TestOptionalEnvVarsRegistry:
|
|||
assert "HERMES_MAX_ITERATIONS" not in OPTIONAL_ENV_VARS
|
||||
|
||||
|
||||
class TestMemoryProviderEnvVarsRegistry:
|
||||
"""Every memory provider that reads an API key from the environment must
|
||||
have that key catalogued in OPTIONAL_ENV_VARS so the dashboard Keys page
|
||||
and `hermes setup` surface it (previously only Honcho was listed, leaving
|
||||
Hindsight/Supermemory/Mem0/RetainDB/ByteRover/OpenViking invisible).
|
||||
|
||||
This is a behavior contract, not a snapshot: it asserts each provider's
|
||||
primary credential key is present, tool-categorised, and password-masked —
|
||||
not a frozen count of entries.
|
||||
"""
|
||||
|
||||
# provider primary-credential env key -> the tool-call name it powers.
|
||||
MEMORY_PROVIDER_KEYS = {
|
||||
"HONCHO_API_KEY": "honcho_context",
|
||||
"HINDSIGHT_API_KEY": "hindsight_recall",
|
||||
"SUPERMEMORY_API_KEY": "supermemory_search",
|
||||
"MEM0_API_KEY": "mem0_search",
|
||||
"RETAINDB_API_KEY": "retaindb_search",
|
||||
"BRV_API_KEY": "brv_query",
|
||||
"OPENVIKING_API_KEY": "viking_search",
|
||||
}
|
||||
|
||||
def test_memory_provider_keys_are_catalogued(self):
|
||||
from hermes_cli.config import OPTIONAL_ENV_VARS
|
||||
missing = [k for k in self.MEMORY_PROVIDER_KEYS if k not in OPTIONAL_ENV_VARS]
|
||||
assert not missing, f"memory provider keys missing from OPTIONAL_ENV_VARS: {missing}"
|
||||
|
||||
def test_memory_provider_keys_are_tool_category(self):
|
||||
from hermes_cli.config import OPTIONAL_ENV_VARS
|
||||
for key in self.MEMORY_PROVIDER_KEYS:
|
||||
assert OPTIONAL_ENV_VARS[key]["category"] == "tool", key
|
||||
|
||||
def test_memory_provider_keys_are_password_masked(self):
|
||||
from hermes_cli.config import OPTIONAL_ENV_VARS
|
||||
for key in self.MEMORY_PROVIDER_KEYS:
|
||||
assert OPTIONAL_ENV_VARS[key].get("password") is True, key
|
||||
|
||||
def test_memory_provider_keys_advertise_their_tool(self):
|
||||
from hermes_cli.config import OPTIONAL_ENV_VARS
|
||||
for key, tool in self.MEMORY_PROVIDER_KEYS.items():
|
||||
assert tool in OPTIONAL_ENV_VARS[key].get("tools", []), key
|
||||
|
||||
|
||||
class TestConfigMigrationSecretPrompts:
|
||||
def test_required_secret_env_prompt_uses_masked_prompt(self, tmp_path, monkeypatch):
|
||||
from hermes_cli import config as cfg_mod
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue