npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

openfeelz

v1.1.1

Published

PAD + Ekman + OCEAN emotional model plugin for OpenClaw agents

Readme

OpenFeelz

"Let's build robots with Genuine People Personalities, they said. So they tried it out with me. I'm a personality prototype. You can tell can't you?" -- Douglas Adams, The Hitchhiker's Guide to the Galaxy

CI License: MIT Node.js TypeScript npm

An OpenClaw plugin that gives AI agents a multidimensional emotional model with personality-influenced decay, rumination, and multi-agent awareness.

Most agents vibes-check each message independently and forget everything between turns. OpenFeelz gives them emotional short-term memory -- the agent knows you've been frustrated for the last three messages, and it carries that context forward. It's not sentience, it's just better interaction design. (But it's pretty cool.)

Features

  • PAD Dimensional Model -- Pleasure, Arousal, Dominance + Connection, Curiosity, Energy, Trust
  • Ekman Basic Emotions -- Happiness, Sadness, Anger, Fear, Disgust, Surprise
  • OCEAN Personality -- Big Five traits influence baselines, decay rates, and response intensity
  • Exponential Decay -- Emotions fade toward personality-influenced baselines over time
  • Rumination Engine -- Intense emotions continue to influence state across interactions
  • Goal-Aware Modulation -- Personality-inferred goals amplify relevant emotions
  • Multi-Agent Awareness -- Agents see other agents' emotional states in the system prompt
  • Custom Taxonomy -- Define your own emotion labels with dimension mappings
  • LLM Classification -- Automatically classify user/agent emotions via OpenAI-compatible models
  • Web Dashboard -- Glassmorphism UI at /emotion-dashboard
  • MCP Server -- Expose emotional state to Cursor, Claude Desktop, etc.
  • CLI Tools -- openclaw emotion status, reset, personality, history, decay (preset or per-dimension), wizard (interactive configuration)

Installation

OpenClaw resolves plugin names from the npm registry, so you can install by package name (no URL or path needed):

openclaw plugins install openfeelz
openclaw plugins enable openfeelz

Restart the gateway after installing. To pin a version: openclaw plugins install [email protected]. To install from a local clone (e.g. for development), run npm run build in the repo first, then openclaw plugins install /path/to/openfeelz.

When using reasoning models (e.g. gpt-5-mini, o1, o3), the classifier omits custom temperature so the API accepts the request. Optional classification logging can be enabled via config (see docs/OPENFEELZ-FIX-COMPLETE.md).

How It Works

Every agent turn, OpenFeelz hooks into the lifecycle:

User sends a message
        |
        v
  [before_agent_start hook]
        |
        v
  1. Load emotion state from disk
  2. Apply exponential decay based on elapsed time
  3. Advance any active rumination entries
  4. Format state into an <emotion_state> XML block
  5. Return as "prependContext" to OpenClaw
        |
        v
  Agent sees emotional context in its system prompt
        |
        v
  [Agent responds]
        |
        v
  [agent_end hook]
        |
        v
  1. Classify emotions in user + agent messages via LLM
  2. Map to dimensional changes
  3. Start rumination if intensity exceeds threshold
  4. Save updated state to disk

What the Agent Sees

The plugin prepends an <emotion_state> block to the system prompt:

<emotion_state>
  <dimensions>
    pleasure: lowered (-0.12), arousal: elevated (0.18), curiosity: elevated (0.72)
  </dimensions>
  <user>
    2026-02-06 09:15: Felt strongly frustrated because deployment keeps failing.
    2026-02-06 08:40: Felt moderately anxious because tight deadline approaching.
    Trend (last 24h): mostly frustrated.
  </user>
  <agent>
    2026-02-06 09:10: Felt moderately focused because working through error logs.
  </agent>
  <others>
    research-agent — 2026-02-06 08:00: Felt mildly curious because investigating new library.
  </others>
</emotion_state>
  • <dimensions> -- PAD dimensions that deviate >0.15 from personality baseline
  • <user> -- Last 3 classified user emotions with timestamps, intensity, and triggers (optional; set includeUserEmotions: true to include; default off due to classification quality)
  • <agent> -- Last 2 agent emotions (continuity across turns)
  • <others> -- Other agents' recent emotional states (up to maxOtherAgents)

The block only appears when there's something to show. Set contextEnabled: false to disable injection while keeping classification, decay, and the dashboard active.

Decay Model

Emotions return to personality-influenced baselines via exponential decay:

newValue = baseline + (currentValue - baseline) * e^(-rate * elapsedHours)
halfLife = ln(2) / rate

Default Rates

| Dimension / Emotion | Rate (per hour) | Half-Life | Notes | |---------------------|-----------------|-----------|-------| | Pleasure | 0.058 | ~12h | | | Arousal | 0.087 | ~8h | Activation calms quickly | | Dominance | 0.046 | ~15h | Sense of control shifts slowly | | Connection | 0.035 | ~20h | Social bonds persist | | Curiosity | 0.058 | ~12h | | | Energy | 0.046 | ~15h | | | Trust | 0.035 | ~20h | Hard-won, slow to fade | | Happiness | 0.058 | ~12h | | | Sadness | 0.046 | ~15h | Lingers longer than joy | | Anger | 0.058 | ~12h | | | Fear | 0.058 | ~12h | | | Disgust | 0.046 | ~15h | | | Surprise | 0.139 | ~5h | Fades the fastest |

Personality Modulation

OCEAN traits adjust decay rates:

  • High neuroticism -- Negative emotions linger (~0.84-0.88x decay rate)
  • High extraversion -- Sadness fades faster (~1.16x), arousal/pleasure recover quicker
  • High agreeableness -- Anger fades faster (~1.12x), connection decays slower
  • High openness -- Curiosity and surprise persist longer

When Decay Runs

Decay is computed on-demand, not on a timer:

  1. before_agent_start -- Primary mechanism. Applied based on elapsed time since last update.
  2. Tool query action -- Decay applied before reading, so values are accurate.
  3. Optional background service -- Set decayServiceEnabled: true for dashboard accuracy between interactions.

Configuring Decay

Four levels of control:

  • Decay preset -- decayPreset: "fast" (~1h half-life, AI-style) or "slow" (human-like, default). Set via config or CLI: openclaw emotion decay fast / openclaw emotion decay slow.
  • Global half-life -- halfLifeHours: 6 (used for context trend window; preset controls actual decay rates).
  • Per-dimension overrides -- "decayRates": { "pleasure": 0.1, "trust": 0.02 } when using decayPreset: "slow" or "custom".
  • Personality-driven -- With slow/custom, OCEAN traits influence baselines and rates; change traits and rates recalculate automatically.

Configuration

In ~/.openclaw/openclaw.json under plugins.entries.openfeelz.config:

{
  "plugins": {
    "entries": {
      "openfeelz": {
        "config": {
          "apiKey": "${OPENAI_API_KEY}",
          "model": "gpt-5-mini",
          "halfLifeHours": 12,
          "ruminationEnabled": true,
          "personality": {
            "openness": 0.7,
            "conscientiousness": 0.6,
            "extraversion": 0.5,
            "agreeableness": 0.8,
            "neuroticism": 0.3
          }
        }
      }
    }
  }
}

Also configurable via the OpenClaw web UI.

Environment Variables

| Variable | Default | Description | |----------|---------|-------------| | OPENAI_API_KEY | (required) | API key for LLM emotion classification | | OPENAI_BASE_URL | https://api.openai.com/v1 | Custom API base URL | | EMOTION_MODEL | gpt-5-mini | Classification model (when OpenAI key present) | | EMOTION_CLASSIFIER_URL | (none) | External HTTP classifier (bypasses LLM) | | EMOTION_HALF_LIFE_HOURS | 12 | Global decay half-life | | EMOTION_CONFIDENCE_MIN | 0.35 | Min confidence threshold | | EMOTION_HISTORY_SIZE | 100 | Max stored stimuli per agent | | EMOTION_TIMEZONE | (system) | IANA timezone for display |

Full Options Reference

| Option | Type | Default | Description | |--------|------|---------|-------------| | apiKey | string | $OPENAI_API_KEY | API key for LLM classification | | baseUrl | string | OpenAI default | API base URL | | model | string | claude-sonnet-4-5 / gpt-5-mini | Classification model (auto-selected by available API key) | | classifierUrl | string | (none) | External classifier URL | | confidenceMin | number | 0.35 | Min confidence threshold | | halfLifeHours | number | 12 | Global decay half-life | | trendWindowHours | number | 24 | Trend computation window | | maxHistory | number | 100 | Max stored stimuli | | ruminationEnabled | boolean | true | Enable rumination engine | | ruminationThreshold | number | 0.7 | Intensity threshold for rumination | | ruminationMaxStages | number | 4 | Max rumination stages | | realtimeClassification | boolean | false | Classify on every message | | contextEnabled | boolean | true | Prepend emotion context to prompt | | includeUserEmotions | boolean | false | Include user/partner emotions in context block (default off due to classification quality) | | decayPreset | "fast" | "slow" | "custom" | "slow" | Decay speed: fast (~1h half-life) or slow (human-like); custom uses decayRates overrides | | decayServiceEnabled | boolean | false | Background decay service | | decayServiceIntervalMinutes | number | 30 | Decay service interval | | dashboardEnabled | boolean | true | Serve web dashboard | | timezone | string | (system) | IANA timezone | | maxOtherAgents | number | 3 | Max other agents in prompt | | emotionLabels | string[] | (21 built-in) | Custom label taxonomy | | personality | object | all 0.5 | OCEAN trait values | | decayRates | object | (see table) | Per-dimension rate overrides | | dimensionBaselines | object | (computed) | Per-dimension baseline overrides |

Agent Tool: emotion_state

The agent can inspect and modify its own emotional state:

| Action | Description | Parameters | |--------|-------------|------------| | query | Get current emotional state | format?: "full" / "summary" / "dimensions" / "emotions" | | modify | Apply an emotional stimulus | emotion, intensity?, trigger? | | set_dimension | Set or adjust a dimension | dimension, value? or dimension, delta? | | reset | Reset to personality baseline | dimensions? (comma-separated, or all) | | set_personality | Set an OCEAN trait | trait, value | | get_personality | Get current OCEAN profile | (none) |

CLI

openclaw emotion status              # Formatted state with bars
openclaw emotion status --json       # Raw JSON
openclaw emotion personality         # OCEAN profile
openclaw emotion personality set --trait openness --value 0.8
openclaw emotion reset               # Reset all to baseline
openclaw emotion reset --dimensions pleasure,arousal
openclaw emotion history --limit 20  # Recent stimuli
openclaw emotion decay fast         # Set decay preset to fast (~1h half-life)
openclaw emotion decay slow         # Set decay preset to slow (human-like, default)
openclaw emotion decay --dimension pleasure --rate 0.05   # Per-dimension override (when not using preset)
openclaw emotion wizard             # Interactive configuration wizard (see below)

Configuration wizard: openclaw emotion wizard

The configuration wizard is the CLI option for guided setup. Run openclaw emotion wizard. It runs an interactive (TUI-style) flow where you can:

  • a) Choose a personality preset — Pick one of 10 famous-personality presets (OCEAN profiles based on biographical research). Each option is listed with a short explanation. The wizard applies that preset’s personality to your agent’s state.
  • b) Customize — Skip presets and go straight to custom settings, or after picking a preset you can optionally configure:
    • Decay speed — Fast (AI-style, emotions fade in ~1 hour) or Slow (human-like, ~12h half-life).
    • Model, decay half-life (trend window), rumination, context injection, and dashboard.

So: run openclaw emotion wizard to open the wizard; it will ask whether you want a preset (with explanations) or custom, then optionally walk through key config fields including decay speed, with validation and help text.

Default personalities in the picker

The preset picker offers these 10 options (diverse across time, region, and domain; OCEAN values from biographical/psychological literature, see docs/personality-presets-research.md):

| Preset | Description | |--------|-------------| | Albert Einstein | Theoretical physicist (Germany/US, 20th c.) — high openness & conscientiousness, introspective. | | Marie Curie | Physicist and chemist (Poland/France, 19th–20th c.) — perseverance, solitary focus. | | Nelson Mandela | Anti-apartheid leader, President of South Africa (20th c.) — high agreeableness & extraversion, emotional stability. | | Wangari Maathai | Environmentalist and Nobel Peace laureate (Kenya, 20th c.) — Green Belt Movement; visionary, resilient. | | Frida Kahlo | Painter (Mexico, 20th c.) — high openness and emotional intensity. | | Confucius | Philosopher and teacher (Ancient China) — high conscientiousness & agreeableness, emphasis on li and ren. | | Simón Bolívar | Liberator and revolutionary (South America, 19th c.) — visionary, charismatic; driven, mood swings. | | Sitting Bull | Lakota leader and resistance figure (Indigenous Americas, 19th c.) — steadfast, defiant sovereignty, calm under pressure. | | Sejong the Great | King and scholar, creator of Hangul (Korea, 15th c.) — scholarly, benevolent, humble. | | Rabindranath Tagore | Poet and philosopher, Nobel laureate (India, 20th c.) — very high openness and agreeableness. |

Choosing a preset updates the agent’s OCEAN personality (and thus baselines and decay rates). You can still edit config manually or via the OpenClaw web UI.

Dashboard

http://localhost:<gateway-port>/emotion-dashboard

Real-time visualization of PAD dimensions, basic emotions, OCEAN profile, recent stimuli, and active rumination. Append ?format=json for the raw API.

MCP Server

Works with any MCP-compatible client (Cursor, Claude Desktop, etc.):

{
  "mcpServers": {
    "openfeelz": {
      "command": "npx",
      "args": ["openfeelz/mcp"]
    }
  }
}

Resources: emotion://state, emotion://personality

Tools: query_emotion, modify_emotion, set_personality

Migration from v1

openclaw hooks disable emotion-state
openclaw emotion migrate

Converts v1 state files (flat labels + string intensities) to v2 format (dimensional model + numeric intensities). Uses a separate state file (openfeelz.json), so no risk of data loss.

Architecture

index.ts                 Plugin entry: registers tool, hooks, service, CLI, dashboard
src/
  types.ts               All interfaces (DimensionalState, BasicEmotions, OCEANProfile, etc.)
  model/
    emotion-model.ts     Core model: clamping, primary detection, intensity, deltas
    personality.ts       OCEAN: baselines, decay rates, rumination probability
    decay.ts             Exponential decay toward personality-influenced baselines
    mapping.ts           Emotion label -> dimension/emotion delta mapping (60+ labels)
    rumination.ts        Multi-stage internal processing for intense emotions
    goal-modulation.ts   Personality-inferred goals amplify relevant emotions
    custom-taxonomy.ts   User-defined emotion labels with custom mappings
  state/
    state-manager.ts     Orchestrator: classify + map + decay + ruminate + persist
    state-file.ts        Atomic JSON I/O with file locking
    multi-agent.ts       Scan sibling agent states for awareness
  classify/
    classifier.ts        Unified LLM + HTTP classifier with fallback
  tool/
    emotion-tool.ts      OpenClaw tool: query/modify/reset/personality
  hook/
    hooks.ts             before_agent_start + agent_end hooks
  cli/
    cli.ts               Commander.js CLI commands
  http/
    dashboard.ts         Glassmorphism HTML dashboard
  mcp/
    mcp-server.ts        MCP server resources + tools
  format/
    prompt-formatter.ts  System prompt <emotion_state> block builder
  migration/
    migrate-v1.ts        v1 -> v2 converter

Development

npm install
npm test              # Run all tests
npm run test:watch    # Watch mode
npm run test:coverage # Coverage report
npm run typecheck     # TypeScript strict mode
npm run lint          # oxlint
npm run build         # Compile to dist/

Contributing

Issues, PRs, and questions are all welcome. If you want to poke around the model or improve it, please do -- I'd love to collaborate. :)

License

MIT


Made with ❤️ by @trianglegrrl for the OpenClaw community 🦞