hermes-paperclip-adapter

repository·main·Indexed 23 days ago

https://github.com/nousresearch/hermes-paperclip-adapter

An adapter that allows the Hermes AI Agent to function as a managed employee within the Paperclip orchestration platform. It bridges Hermes's autonomous capabilities—including tools, skills, and memory—with Paperclip's task management and UI. The adapter manages the execution lifecycle by spawning the Hermes CLI in single-query mode, parsing stdout/stderr into structured TranscriptEntry objects, and maintaining conversation context across heartbeats using the --resume flag.

Tokens
5K
Snippets
6
Records
26
Agent score
73%

What's inside hermes-paperclip-adapter

  1. How the Hermes adapter works

    main

    The adapter acts as a bridge between the Paperclip orchestration platform and the Hermes Agent CLI.

    Execution Lifecycle

    1. Trigger: Paperclip triggers a run via a heartbeat, a task assignment, or a comment wake.
    2. Execution: The adapter spawns the Hermes CLI in single-query mode (-q).
    3. Parsing: The adapter captures stdout/stderr and parses it into structured TranscriptEntry objects. This allows Paperclip to render tool cards with status icons.
    4. Post-processing: Raw Hermes ASCII formatting (banners, setext headings, table borders) is converted into clean GFM markdown for the Paperclip UI.
    5. Error Handling: Benign stderr messages (like MCP initialization or structured logs) are reclassified so they do not appear as errors in the UI.
    6. Persistence: The adapter uses Hermes's --resume flag to maintain conversation context, memories, and tool state across heartbeats. The sessionCodec ensures session state is validated and migrated correctly between runs.

    Skills Integration

    The adapter provides a unified view of skills by merging two sources:

    • Paperclip-managed skills: Bundled with the adapter and togglable via the UI.
    • Hermes-native skills: Located in ~/.hermes/skills/ (read-only).

    The listSkills and syncSkills APIs allow the Paperclip UI to display both types in a single view.

  2. Register the Hermes adapter in your Paperclip server

    main

    To enable the adapter, you must register it in your Paperclip server's adapter registry (typically located at server/src/adapters/registry.ts). You need to import the adapter and its specific server-side functions: execute, testEnvironment, detectModel, listSkills, syncSkills, and sessionCodec.

    import * as hermesLocal from "hermes-paperclip-adapter";
    import {
      execute,
      testEnvironment,
      detectModel,
      listSkills,
      syncSkills,
      sessionCodec,
    } from "hermes-paperclip-adapter/server";
    
    registry.set("hermes_local", {
      ...hermesLocal,
      execute,
      testEnvironment,
      detectModel,
      listSkills,
      syncSkills,
      sessionCodec,
    });
  3. Configure the Hermes adapter settings

    main

    The adapter accepts several configuration categories to control how the Hermes Agent behaves within Paperclip.

    Core Settings

    • model (string): Model in provider/model format. Default: anthropic/claude-sonnet-4.
    • provider (string): API provider. Options: auto, openrouter, nous, openai-codex, zai, kimi-coding, minimax, minimax-cn. (Auto-detected if not set).
    • timeoutSec (number): Execution timeout in seconds. Default: 300.
    • graceSec (number): Grace period before SIGKILL. Default: 10.

    Tools

    • toolsets (string): Comma-separated toolsets to enable. Default: all. Available: terminal, file, web, browser, code_execution, vision, mcp, creative, productivity.

    Session & Workspace

    • persistSession (boolean): Resume sessions across heartbeats. Default: true.
    • worktreeMode (boolean): Use Git worktree isolation. Default: false.
    • checkpoints (boolean): Enable filesystem checkpoints for rollback. Default: false.

    Advanced

    • hermesCommand (string): Custom CLI binary path. Default: hermes.
    • verbose (boolean): Enable verbose output. Default: false.
    • quiet (boolean): Quiet mode (clean output, no banner/spinner). Default: true.
    • extraArgs (string[]): Additional CLI arguments. Default: [].
    • env (object): Extra environment variables. Default: {}.
    • paperclipApiUrl (string): Paperclip API base URL. Default: http://127.0.0.1:3100/api.
  4. Use template variables in Hermes prompt templates

    main

    If you provide a custom promptTemplate in the Hermes configuration, you can use the following variables to inject context from the Paperclip environment:

    • {{agentId}}: Paperclip agent ID
    • {{agentName}}: Agent display name
    • {{companyId}}: Paperclip company ID
    • {{companyName}}: Company display name
    • {{runId}}: Current heartbeat run ID
    • {{taskId}}: Current task/issue ID (if assigned)
    • {{taskTitle}}: Task title (if assigned)
    • {{taskBody}}: Task description (if assigned)
    • {{projectName}}: Project name (if scoped to a project)
  5. Customize the Hermes prompt template

    main

    You can provide a custom promptTemplate using {{variable}} syntax to control how tasks are presented to the agent.

    Available Variables

    • {{agentId}}: Paperclip agent ID
    • {{agentName}}: Agent display name
    • {{companyId}}: Company ID
    • {{companyName}}: Company name
    • {{runId}}: Current heartbeat run ID
    • {{taskId}}: Assigned task/issue ID
    • {{taskTitle}}: Task title
    • {{taskBody}}: Task instructions
    • {{projectName}}: Project name
    • {{paperclipApiUrl}}: Paperclip API base URL
    • {{commentId}}: Comment ID (when woken by a comment)
    • {{wakeReason}}: Reason this run was triggered

    Conditional Sections

    • {{#taskId}}...{{/taskId}}: Included only when a task is assigned.
    • {{#noTask}}...{{/noTask}}: Included only when no task is present (heartbeat check).
    • {{#commentId}}...{{/commentId}}: Included only when woken by a comment.
  6. Understand Hermes model-to-provider inference

    main

    If no explicit provider is configured, the adapter attempts to infer the correct provider by matching the model name against known prefixes. The following mapping is used:

    Model PrefixInferred Provider
    gpt-4openai-codex
    gpt-5copilot
    o1-, o3-, o4-openai-codex
    claudeanthropic
    geminiauto
    hermes-nous
    glm-zai
    moonshot, kimikimi-coding
    minimaxminimax
    deepseek, llama, qwen, mistralauto
    huggingface/huggingface
  7. How provider resolution works

    main

    When determining which provider to use for a model, the adapter follows a specific priority chain to ensure correct routing. The resolution order is:

    1. Explicit Provider: If an explicitProvider is provided via the adapterConfig (user override), it takes highest priority.
    2. Hermes Config: If a provider is defined in ~/.hermes/config.yaml, it is used only if the detectedModel in the config matches the requested model name (case-insensitive).
    3. Model Inference: If no explicit or config-based provider is found, the adapter attempts to infer the provider from the model name prefix (e.g., gpt- might map to copilot).
    4. Auto: If all else fails, the provider defaults to auto, allowing Hermes to handle detection.
  8. Configure the Hermes Agent adapter

    main

    When configuring a Hermes agent in the Paperclip UI, you can provide several configuration fields to control the agent's behavior, tools, and environment.

    Prerequisites

    • Python 3.10+ installed
    • Hermes Agent installed via pip install hermes-agent
    • At least one LLM API key configured in ~/.hermes/.env

    Core Configuration

    • model (string): Optional explicit model in provider/model format. Leave blank to use Hermes's configured default.
    • provider (string): API provider (e.g., auto, openrouter, nous, openai-codex, zai, kimi-coding, minimax, minimax-cn). Usually not needed as Hermes auto-detects from the model name.
    • timeoutSec (number): Execution timeout in seconds (default: 300).
    • graceSec (number): Grace period after SIGTERM before SIGKILL (default: 10).

    Tool Configuration

    • toolsets (string): Comma-separated toolsets to enable (e.g., "terminal,file,web"). Default is "all".

    Session & Workspace

    • persistSession (boolean): Resume sessions across heartbeats (default: true).
    • worktreeMode (boolean): Use git worktree for isolated changes (default: false).
    • checkpoints (boolean): Enable filesystem checkpoints (default: false).

    Advanced

    • hermesCommand (string): Path to hermes CLI binary (default: "hermes").
    • verbose (boolean): Enable verbose output (default: false).
    • extraArgs (string[]): Additional CLI arguments (default: []).
    • env (object): Extra environment variables (default: {}).
    • promptTemplate (string): Custom prompt template using {{variable}} placeholders.
  9. Create a Hermes agent in Paperclip

    main

    Once registered, create an agent in the Paperclip UI or via API using the hermes_local adapter type. You can configure the model, iteration limits, timeouts, and enabled toolsets in the adapterConfig object.

    {
      "name": "Hermes Engineer",
      "adapterType": "hermes_local",
      "adapterConfig": {
        "model": "anthropic/claude-sonnet-4",
        "maxIterations": 50,
        "timeoutSec": 300,
        "persistSession": true,
        "enabledToolsets": ["terminal", "file", "web"]
      }
    }
  10. Configure the Hermes config.yaml for model settings

    main

    The Hermes adapter reads model configuration from ~/.hermes/config.yaml. To define your default model and its associated settings, use the model: section in the YAML file.

    Supported keys under the model: section:

    • default: The model name (e.g., gpt-5.4 or anthropic/claude-sonnet-4).
    • provider: The provider name (e.g., copilot, zai, anthropic).
    • base_url: An optional base URL override for the API.
    • api_mode: The API mode to use (e.g., chat_completions, codex_responses).
  11. Detect and resolve models and providers

    main

    The adapter provides utilities to identify which LLM model is being used and which provider (e.g., OpenAI, Anthropic) is responsible for it. This is useful for configuring agent capabilities based on the underlying model.

    Available functions:

    • detectModel: Identifies a model from input.
    • parseModelFromConfig: Extracts model information from a configuration object.
    • resolveProvider: Determines the provider for a given model.
    • inferProviderFromModel: Infers the provider based on the model name.
    import {
      detectModel,
      parseModelFromConfig,
      resolveProvider,
      inferProviderFromModel
    } from "./detect-model.js";