mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-29 23:41:35 +08:00
Compare commits
3 Commits
fix/plugin
...
fix/hindsi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2246c81d0d | ||
|
|
8877688b34 | ||
|
|
9d42aca29a |
@@ -478,7 +478,9 @@ class HindsightMemoryProvider(MemoryProvider):
|
||||
existing = {}
|
||||
if config_path.exists():
|
||||
try:
|
||||
existing = json.loads(config_path.read_text())
|
||||
parsed = json.loads(config_path.read_text())
|
||||
if isinstance(parsed, dict):
|
||||
existing = parsed
|
||||
except Exception:
|
||||
pass
|
||||
existing.update(values)
|
||||
@@ -589,12 +591,35 @@ class HindsightMemoryProvider(MemoryProvider):
|
||||
val = input(f" LLM model [{default_model}]: ").strip()
|
||||
provider_config["llm_model"] = val or default_model
|
||||
|
||||
sys.stdout.write(" LLM API key: ")
|
||||
existing_llm_key = os.environ.get("HINDSIGHT_LLM_API_KEY", "")
|
||||
if not existing_llm_key:
|
||||
existing_llm_key = _load_simple_env(Path(hermes_home) / ".env").get(
|
||||
"HINDSIGHT_LLM_API_KEY",
|
||||
"",
|
||||
)
|
||||
if not existing_llm_key:
|
||||
saved_config = dict(provider_config)
|
||||
config_path = Path(hermes_home) / "hindsight" / "config.json"
|
||||
try:
|
||||
parsed = json.loads(config_path.read_text(encoding="utf-8"))
|
||||
if isinstance(parsed, dict):
|
||||
saved_config.update(parsed)
|
||||
except Exception:
|
||||
pass
|
||||
saved_config.update(provider_config)
|
||||
existing_llm_key = _load_simple_env(
|
||||
_embedded_profile_env_path(saved_config)
|
||||
).get("HINDSIGHT_API_LLM_API_KEY", "")
|
||||
|
||||
if existing_llm_key:
|
||||
masked = f"...{existing_llm_key[-4:]}" if len(existing_llm_key) > 4 else "set"
|
||||
sys.stdout.write(f" LLM API key (current: {masked}, blank to keep): ")
|
||||
else:
|
||||
sys.stdout.write(" LLM API key: ")
|
||||
sys.stdout.flush()
|
||||
llm_key = getpass.getpass(prompt="") if sys.stdin.isatty() else sys.stdin.readline().strip()
|
||||
# Always write explicitly (including empty) so the provider sees ""
|
||||
# rather than a missing variable. The daemon reads from .env at
|
||||
# startup and fails when HINDSIGHT_LLM_API_KEY is unset.
|
||||
if not llm_key and existing_llm_key:
|
||||
llm_key = existing_llm_key
|
||||
env_writes["HINDSIGHT_LLM_API_KEY"] = llm_key
|
||||
|
||||
# Step 4: Save everything
|
||||
@@ -602,7 +627,9 @@ class HindsightMemoryProvider(MemoryProvider):
|
||||
provider_config["recall_budget"] = "mid"
|
||||
# Read existing timeout from config if present, otherwise use default
|
||||
existing_timeout = self._config.get("timeout") if self._config else None
|
||||
timeout_val = existing_timeout if existing_timeout else _DEFAULT_TIMEOUT
|
||||
if not existing_timeout:
|
||||
existing_timeout = _load_simple_env(Path(hermes_home) / ".env").get("HINDSIGHT_TIMEOUT")
|
||||
timeout_val = int(existing_timeout) if existing_timeout else _DEFAULT_TIMEOUT
|
||||
provider_config["timeout"] = timeout_val
|
||||
env_writes["HINDSIGHT_TIMEOUT"] = str(timeout_val)
|
||||
config["memory"]["provider"] = "hindsight"
|
||||
|
||||
@@ -504,6 +504,8 @@ AUTHOR_MAP = {
|
||||
"screenmachine@gmail.com": "teknium1",
|
||||
"chenzeshi@live.com": "chen1749144759",
|
||||
"mor.aleksandr@yahoo.com": "MorAlekss",
|
||||
"poruru.code@gmail.com": "poruru-code",
|
||||
"138243371+poruru-code@users.noreply.github.com": "poruru-code",
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -329,8 +329,89 @@ class TestPostSetup:
|
||||
|
||||
profile_env = user_home / ".hindsight" / "profiles" / "hermes.env"
|
||||
assert profile_env.exists()
|
||||
assert (hermes_home / ".env").read_text() == "HINDSIGHT_LLM_API_KEY=existing-key\nHINDSIGHT_TIMEOUT=120\n"
|
||||
assert "HINDSIGHT_API_LLM_API_KEY=existing-key\n" in profile_env.read_text()
|
||||
|
||||
def test_local_embedded_setup_preserves_existing_key_from_nondefault_profile_env_when_input_left_blank(self, tmp_path, monkeypatch):
|
||||
hermes_home = tmp_path / "hermes-home"
|
||||
user_home = tmp_path / "user-home"
|
||||
user_home.mkdir()
|
||||
monkeypatch.setenv("HOME", str(user_home))
|
||||
|
||||
selections = iter([1, 0]) # local_embedded, openai
|
||||
monkeypatch.setattr("hermes_cli.memory_setup._curses_select", lambda *args, **kwargs: next(selections))
|
||||
monkeypatch.setattr("shutil.which", lambda name: None)
|
||||
monkeypatch.setattr("builtins.input", lambda prompt="": "")
|
||||
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
|
||||
monkeypatch.setattr("getpass.getpass", lambda prompt="": "")
|
||||
monkeypatch.setattr("hermes_cli.config.save_config", lambda cfg: None)
|
||||
|
||||
provider = HindsightMemoryProvider()
|
||||
provider.save_config({"profile": "coder"}, str(hermes_home))
|
||||
|
||||
profile_env = user_home / ".hindsight" / "profiles" / "coder.env"
|
||||
profile_env.parent.mkdir(parents=True, exist_ok=True)
|
||||
profile_env.write_text("HINDSIGHT_API_LLM_API_KEY=existing-key\n")
|
||||
|
||||
provider.post_setup(str(hermes_home), {"memory": {}})
|
||||
|
||||
assert (hermes_home / ".env").read_text() == "HINDSIGHT_LLM_API_KEY=existing-key\nHINDSIGHT_TIMEOUT=120\n"
|
||||
assert "HINDSIGHT_API_LLM_API_KEY=existing-key\n" in profile_env.read_text()
|
||||
|
||||
def test_local_embedded_setup_ignores_nondict_saved_config_when_input_left_blank(self, tmp_path, monkeypatch):
|
||||
hermes_home = tmp_path / "hermes-home"
|
||||
user_home = tmp_path / "user-home"
|
||||
user_home.mkdir()
|
||||
monkeypatch.setenv("HOME", str(user_home))
|
||||
|
||||
selections = iter([1, 0]) # local_embedded, openai
|
||||
monkeypatch.setattr("hermes_cli.memory_setup._curses_select", lambda *args, **kwargs: next(selections))
|
||||
monkeypatch.setattr("shutil.which", lambda name: None)
|
||||
monkeypatch.setattr("builtins.input", lambda prompt="": "")
|
||||
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
|
||||
monkeypatch.setattr("getpass.getpass", lambda prompt="": "")
|
||||
monkeypatch.setattr("hermes_cli.config.save_config", lambda cfg: None)
|
||||
|
||||
config_path = hermes_home / "hindsight" / "config.json"
|
||||
config_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
config_path.write_text("[]")
|
||||
|
||||
env_path = hermes_home / ".env"
|
||||
env_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
env_path.write_text("HINDSIGHT_LLM_API_KEY=existing-key\n")
|
||||
|
||||
provider = HindsightMemoryProvider()
|
||||
provider.post_setup(str(hermes_home), {"memory": {}})
|
||||
|
||||
profile_env = user_home / ".hindsight" / "profiles" / "hermes.env"
|
||||
assert profile_env.exists()
|
||||
assert (hermes_home / ".env").read_text() == "HINDSIGHT_LLM_API_KEY=existing-key\nHINDSIGHT_TIMEOUT=120\n"
|
||||
assert "HINDSIGHT_API_LLM_API_KEY=existing-key\n" in profile_env.read_text()
|
||||
|
||||
def test_local_embedded_setup_preserves_existing_timeout(self, tmp_path, monkeypatch):
|
||||
hermes_home = tmp_path / "hermes-home"
|
||||
user_home = tmp_path / "user-home"
|
||||
user_home.mkdir()
|
||||
monkeypatch.setenv("HOME", str(user_home))
|
||||
|
||||
selections = iter([1, 0]) # local_embedded, openai
|
||||
monkeypatch.setattr("hermes_cli.memory_setup._curses_select", lambda *args, **kwargs: next(selections))
|
||||
monkeypatch.setattr("shutil.which", lambda name: None)
|
||||
monkeypatch.setattr("builtins.input", lambda prompt="": "")
|
||||
monkeypatch.setattr("sys.stdin.isatty", lambda: True)
|
||||
monkeypatch.setattr("getpass.getpass", lambda prompt="": "sk-test")
|
||||
monkeypatch.setattr("hermes_cli.config.save_config", lambda cfg: None)
|
||||
|
||||
env_path = hermes_home / ".env"
|
||||
env_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
env_path.write_text("HINDSIGHT_LLM_API_KEY=sk-test\nHINDSIGHT_TIMEOUT=300\n")
|
||||
|
||||
provider = HindsightMemoryProvider()
|
||||
provider.post_setup(str(hermes_home), {"memory": {}})
|
||||
|
||||
env_content = (hermes_home / ".env").read_text()
|
||||
assert "HINDSIGHT_TIMEOUT=300" in env_content
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Tool handler tests
|
||||
|
||||
Reference in New Issue
Block a user