Files
hermes-identity-plugin/docs/honcho-injector.md
Hermes 172fa90b25 initial: identity resolution plugin
- Plugin manifest (plugin.yaml) with pre_gateway_dispatch + on_session_start hooks
- /identity slash command for config management
- Honcho injector patch docs (6 lines in plugins/memory/honcho/__init__.py)
- Config file at /opt/data/identity-config.json for persistence
- Kanban task body convention: context_peer: <name>
- Sample config with thierry/catherine mappings

Architecture: user-installed plugin (hooks + CLI) + 6-line Honcho bundled plugin change
2026-05-24 16:02:55 -04:00

3.7 KiB

Honcho Injector Patch

The identity plugin cannot directly inject runtime_user_peer_name into Honcho from a user-installed hook (the hook system only allows message rewrite/skip, not user_id modification). Instead, we add ~6 lines in the bundled Honcho plugin's session initialization.

File

plugins/memory/honcho/__init__.py — line ~362

The change

Before

runtime_user_peer_name=kwargs.get("user_id") or None,

After

runtime_user_peer_name=kwargs.get("user_id") or _resolve_identity_peer(),

Add this function in the same file (or import from the identity plugin)

def _resolve_identity_peer() -> str | None:
    """Resolve peer name from env vars and identity config.

    Priority: HERMES_HONCHO_PEER_NAME → kanban task body context_peer
    → kanban board config → None (falls through to Honcho default).
    """
    import json, os, sqlite3, re
    from pathlib import Path

    # 1. Explicit env override
    explicit = os.environ.get("HERMES_HONCHO_PEER_NAME")
    if explicit:
        return explicit

    # 2. Kanban worker: read task body for context_peer
    task_id = os.environ.get("HERMES_KANBAN_TASK")
    db_path = os.environ.get("HERMES_KANBAN_DB")
    if task_id and db_path:
        db = Path(db_path)
        if db.exists():
            try:
                conn = sqlite3.connect(str(db))
                conn.row_factory = sqlite3.Row
                try:
                    row = conn.execute(
                        "SELECT body FROM tasks WHERE id = ?", (task_id,)
                    ).fetchone()
                    if row and row["body"]:
                        m = re.search(r"context_peer:\s*(\S+)", row["body"])
                        if m:
                            return m.group(1)
                finally:
                    conn.close()
            except Exception:
                pass

    # 3. Identity config file
    cfg_path = Path("/opt/data/identity-config.json")
    if cfg_path.exists():
        try:
            cfg = json.loads(cfg_path.read_text())
            # Check kanban board config
            board = os.environ.get("HERMES_KANBAN_BOARD")
            if board and board in cfg.get("boards", {}):
                return cfg["boards"][board]
            # Use fallback
            return cfg.get("fallback_peer")
        except Exception:
            pass

    return None

How it works

  1. When a gateway session starts, kwargs["user_id"] carries the platform ID (Discord snowflake, Telegram UID). The identity config file maps these to canonical peer names. The injector is bypassed — normal flow.

  2. When a kanban worker starts, kwargs["user_id"] is None (no gateway). The injector kicks in:

    a. Checks HERMES_HONCHO_PEER_NAME env var (set by a future dispatcher enhancement or manually).

    b. Reads the kanban task body from the SQLite database, extracts context_peer: <name> from the body.

    c. Falls back to the board-level config from identity-config.json.

    d. If nothing resolves → returns None → Honcho creates user-default-* as today (safe fallback).

Why not modify the kanban dispatcher?

The kanban dispatcher (hermes_cli/kanban_db.py:_default_spawn) is core Hermes code. We avoid touching it. Instead, the Honcho injector reads the task directly from the kanban DB using env vars that are already set (HERMES_KANBAN_TASK, HERMES_KANBAN_DB, HERMES_KANBAN_BOARD).

This adds ~10 microseconds to worker startup — negligible.

Compatibility

  • If the identity plugin is removed, the injector function returns None and Honcho behaves exactly as before.
  • If the config file is missing, same safe fallback.
  • No data loss risk.