This commit is contained in:
@@ -21,6 +21,9 @@
|
||||
|
||||
extraPackages = with pkgs; [ nix git ripgrep fd jq codex ];
|
||||
|
||||
# Pulls in hindsight-client (the HTTP client lib the memory plugin uses).
|
||||
extraDependencyGroups = [ "hindsight" ];
|
||||
|
||||
environment = {
|
||||
SIGNAL_HTTP_URL = "http://127.0.0.1:8080";
|
||||
CODEX_HOME = "/var/lib/hermes/.codex";
|
||||
@@ -44,14 +47,14 @@
|
||||
toolsets = [ "all" ];
|
||||
terminal.backend = "local";
|
||||
|
||||
# Self-hosted memory: pure SQLite in-process, no external services or
|
||||
# API keys. db file lives under HERMES_HOME (= /var/lib/hermes/.hermes),
|
||||
# which is on the persisted bind-mount.
|
||||
memory.provider = "holographic";
|
||||
plugins.hermes-memory-store = {
|
||||
db_path = "/var/lib/hermes/.hermes/memory_store.db";
|
||||
auto_extract = true;
|
||||
default_trust = 0.5;
|
||||
# Memory lives in a sibling hindsight-api process (see systemd unit
|
||||
# below) backed by system postgres. Plugin talks HTTP to it locally.
|
||||
memory.provider = "hindsight";
|
||||
plugins.hermes-hindsight = {
|
||||
mode = "local_external";
|
||||
api_url = "http://127.0.0.1:8888";
|
||||
bank_id = "hermes";
|
||||
memory_mode = "hybrid";
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -80,6 +83,8 @@
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /var/lib/hermes/.codex 0700 googlebot users -"
|
||||
"C+ /var/lib/hermes/.codex/config.toml 0644 googlebot users - /etc/hermes-codex-config.toml"
|
||||
"d /var/lib/hermes/hindsight 0700 googlebot users -"
|
||||
"d /var/lib/hermes/postgresql 0750 postgres postgres -"
|
||||
];
|
||||
|
||||
# signal-cli runs an HTTP JSON-RPC daemon on localhost; hermes-agent talks to
|
||||
@@ -102,4 +107,103 @@
|
||||
RestartSec = "5";
|
||||
};
|
||||
};
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Hindsight memory backend
|
||||
#
|
||||
# Architecture:
|
||||
# hermes-agent --HTTP--> hindsight-api (port 8888) --asyncpg--> postgres
|
||||
# hindsight-worker (background async retain/reflect)
|
||||
#
|
||||
# The api + worker run as googlebot with HOME=/var/lib/hermes so the
|
||||
# `openai-codex` provider's hardcoded Path.home() / ".codex" / "auth.json"
|
||||
# resolves to the persisted codex tokens.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_17;
|
||||
extensions = ps: [ ps.pgvector ];
|
||||
# Persist DB state on the /var/lib/hermes bind mount so the hindsight
|
||||
# memory bank survives `nixos-rebuild switch` (which recreates the
|
||||
# incus container and wipes its writable layer).
|
||||
dataDir = "/var/lib/hermes/postgresql/17";
|
||||
ensureDatabases = [ "hindsight" ];
|
||||
ensureUsers = [{
|
||||
name = "googlebot";
|
||||
# Superuser so the hindsight-api alembic migrations can `CREATE EXTENSION`
|
||||
# and own the schema. Acceptable here because postgres is local-only to
|
||||
# the sandboxed workspace and only talks to hindsight-api over the unix
|
||||
# socket.
|
||||
ensureClauses.superuser = true;
|
||||
}];
|
||||
};
|
||||
|
||||
systemd.services.hindsight-api =
|
||||
let
|
||||
env = {
|
||||
# Connection — postgres is on the local unix socket; sqlalchemy gets
|
||||
# an asyncpg URL via the asyncpg+host=<socket-dir> trick.
|
||||
HINDSIGHT_API_DATABASE_URL = "postgresql+asyncpg:///hindsight?host=/run/postgresql";
|
||||
HINDSIGHT_API_HOST = "127.0.0.1";
|
||||
HINDSIGHT_API_PORT = "8888";
|
||||
|
||||
# LLM + embeddings both ride codex OAuth — no separate keys.
|
||||
HINDSIGHT_API_LLM_PROVIDER = "openai-codex";
|
||||
HINDSIGHT_API_EMBEDDINGS_PROVIDER = "openai-codex";
|
||||
|
||||
# We did not install [local-ml] extras, so disable the reranker
|
||||
# (default is "local" which requires sentence-transformers).
|
||||
HINDSIGHT_API_RERANKER_PROVIDER = "none";
|
||||
|
||||
# HOME drives where the codex auth file is read from
|
||||
# (CodexLLM/CodexOAuthEmbeddings: Path.home() / ".codex" / "auth.json").
|
||||
HOME = "/var/lib/hermes";
|
||||
};
|
||||
in
|
||||
{
|
||||
description = "Hindsight memory API server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "postgresql.service" "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
requires = [ "postgresql.service" ];
|
||||
before = [ "hermes-agent.service" ];
|
||||
environment = env;
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "googlebot";
|
||||
Group = "users";
|
||||
ExecStart = "${pkgs.hindsight-api}/bin/hindsight-api";
|
||||
Restart = "always";
|
||||
RestartSec = "5";
|
||||
WorkingDirectory = "/var/lib/hermes/hindsight";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.hindsight-worker =
|
||||
let
|
||||
env = {
|
||||
HINDSIGHT_API_DATABASE_URL = "postgresql+asyncpg:///hindsight?host=/run/postgresql";
|
||||
HINDSIGHT_API_LLM_PROVIDER = "openai-codex";
|
||||
HINDSIGHT_API_EMBEDDINGS_PROVIDER = "openai-codex";
|
||||
HINDSIGHT_API_RERANKER_PROVIDER = "none";
|
||||
HOME = "/var/lib/hermes";
|
||||
};
|
||||
in
|
||||
{
|
||||
description = "Hindsight background worker (async retain / reflect)";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "hindsight-api.service" ];
|
||||
requires = [ "hindsight-api.service" ];
|
||||
environment = env;
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "googlebot";
|
||||
Group = "users";
|
||||
ExecStart = "${pkgs.hindsight-api}/bin/hindsight-worker";
|
||||
Restart = "always";
|
||||
RestartSec = "5";
|
||||
WorkingDirectory = "/var/lib/hermes/hindsight";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user