{ pkgs, lib, config, ... }: let
  hermes-agent = import ./package.nix;
in {
  imports = [
    ./container-service
  ];

  home.packages = [
    hermes-agent
  ];
  home.shellAliases.hermes-tui = "hermes --tui";

  yq-merge.".hermes/config.yaml" = {
    generator = builtins.toJSON;
    yqExtraArgs = "-P";
    expr = {
      model = {
        default = config.ai.minimax-china.default_large_model_id;
        provider = "minimax-cn";
        base_url = config.ai.minimax-china.api_endpoint;
      };
      # the avaliable fields see: <hermes-agent>/hermes_cli/config.py: _normalize_custom_provider_entry
      providers = {
        jw-claude = {
          name = "JW Claude";
          api = config.ai.jw-claude.api_endpoint;
          api_key = config.ai.jw-claude.api_key;
          transport = "anthropic_messages";
        };
        jw-codex = {
          name = "JW Codex";
          api = config.ai.jw-codex.api_endpoint;
          api_key = config.ai.jw-codex.api_key;
          transport = "codex_responses";
          models."${config.ai.jw-codex.default_large_model_id}".context_length
            = config.ai.jw-codex.models."${config.ai.jw-codex.default_large_model_id}".context_window;
          models."${config.ai.jw-codex.default_small_model_id}".context_length
            = config.ai.jw-codex.models."${config.ai.jw-codex.default_small_model_id}".context_window;
        };
      };
      compression = {
        enabled = true;
        threshold = 0.8;
      };
      web = {
        backend = "tavily";
        search_backend = "tavily";
        extract_backend = "tavily";
      };
      # CLI vs TUI
      # CLI
      # - Cons
      #   - No session selection UI
      #   - Does not support `/background`: the `/background` behavior is the same as /queue
      # TUI
      # - Cons
      #   - The providers/models selection UI does not filter out un-configured providers.
      #   - The scroll sometimes jump/glitch
      #   - Does not respect tool_preview_length = 0
      display = {
        show_reasoning = true;
        # The hermes verbose does not output gracefully: the newline is printde as "\n"!
        tool_progress = "all";
        tool_preview_length = 0; # unlimited
        tui_compact = false;
        streaming = true;
        final_response_markdown = "render";
      };
      mcp_servers = {
        ddgs = { inherit (config.ai.mcp.ddgs) command args; };
      };
    };
  };
  yq-merge.".hermes/.env" = {
    generator = lib.generators.toKeyValue {};
    yqExtraArgs = "-p=props -o=props --properties-separator='='";
    expr = {
      KIMI_API_KEY = config.ai.kimi.api_key;
      MINIMAX_CN_API_KEY = config.ai.minimax-china.api_key;
      TAVILY_API_KEY = config.ai.tavily.api_key;
    };
  };

  # zsh completion via fpath (not eval, which breaks _arguments)
  # https://github.com/NousResearch/hermes-agent/issues/6122
  home.file."zsh-completions/_hermes" = {
    target = ".zsh/completions/_hermes";
    source = pkgs.runCommand "hermes-zsh-completion" {} ''
      ${hermes-agent}/bin/hermes completion zsh > $out
    '';
  };
  programs.zsh.initContent = lib.mkBefore ''
    fpath+=("$HOME/.zsh/completions")
  '';

  home.file.".hermes/memories/USER.md".source = config.lib.file.mkOutOfStoreSymlink ~/Gist/Data/hermes/memories/USER.md;
  home.file.".hermes/memories/MEMORY.md".source = config.lib.file.mkOutOfStoreSymlink ~/Gist/Data/hermes/memories/MEMORY.md;
  home.file.".hermes/skills".source = config.lib.file.mkOutOfStoreSymlink ~/Gist/Data/hermes/skills;
  home.file.".hermes/skill-bundles".source = config.lib.file.mkOutOfStoreSymlink ~/Gist/Data/hermes/skill-bundles;
}