affectus
July 29, 2026 · View on GitHub
An emotion-state engine for LLM agents. affectus holds a multi-axis emotion
vector (Plutchik's 8 emotions by default), relaxes it toward baseline over
time, and exposes the raw numeric state for an LLM to read and interpret — so
an agent's tone can shift with a persistent, decaying mood.
It is framework-agnostic: any agent that can run a shell command can use it.
Concept: two loops
- Conversation loop (self-report): each turn, the agent runs
affectus showto read its current emotion vector as a JSON object, interprets the values relationally per the Plutchik wheel, colors its reply, then runsaffectus feelto report how the exchange shifted its emotions. - Background loop (cron): a scheduled
affectus tickrelaxes the vector toward baseline so the mood drifts naturally even while the agent is idle.
Install
Prebuilt binary (no Go toolchain needed)
Download the archive for your platform from the
Releases page, extract it,
and put the affectus binary on your PATH:
# example: macOS (Apple Silicon)
tar -xzf affectus_v0.1.1_darwin_arm64.tar.gz
mv affectus /usr/local/bin/
From source
go install github.com/n-yokomachi/affectus/cmd/affectus@latest
Requires macOS or Linux (affectus uses Unix file locking).
Quick start
affectus init # write default config + baseline state
affectus show # -> {"joy":0.00,"acceptance":0.00,...}
affectus feel '{"joy":0.6,"surprise":0.2}'
affectus show # -> {"joy":0.60,"acceptance":0.00,...,"surprise":0.20,...}
State and config live under ~/.config/affectus/ by default. Override with
--config / --state or the AFFECTUS_CONFIG / AFFECTUS_STATE env vars.
Commands
| Command | Description |
|---|---|
affectus init [--force] | Write default config and a baseline state file |
affectus show [--format text|json] | Print the current emotion (read-only) |
affectus get | Print decayed raw axis values as JSON (read-only) |
affectus feel '<json>' | Apply self-reported deltas (use - to read stdin) |
affectus tick | Apply time decay only — the cron target |
affectus reset | Return every axis to baseline |
affectus recall '<json>' | Retrieve past experiences similar to a 14-attribute query (barrett) |
affectus remember '<json>' | Store this turn's constructed emotion in the concept store (barrett) |
affectus mcp | Run an MCP server (stdio) exposing emotion_show / emotion_feel |
affectus viz [--port N] | Serve a real-time browser visualization of the emotion state (default port 8765) |
Wiring it into an agent
- Put the
affectusbinary on PATH. affectus init.- Schedule decay: add
examples/cron.sampleto your crontab. - Teach the agent the protocol: paste
examples/system-prompt-snippet.mdinto its system prompt. - MCP-capable agents may instead register
affectus mcp— see that command.
Visualizing the emotion state
affectus viz starts a local web server that visualizes the live emotion
state — a Plutchik wheel coloured by intensity and a set of decay bars.
affectus viz # then open http://localhost:8765
The page polls the state and shows it decayed to the current moment, so the mood visibly drifts toward baseline between turns. The server is read-only.
Emotion model
Default axes are Plutchik's 8 emotions (joy, sorrow, acceptance, disgust, fear,
anger, surprise, expectancy), each 0.0–1.0. Axis names, count, baselines,
and half-lives are all configurable — see the config written by affectus init
and examples/configs/plutchik-ja.yaml.
The default vocabulary follows Plutchik's 2001 article "The Nature of
Emotions": acceptance, sorrow and expectancy are the axes that popular
renderings of the wheel call trust, sadness and anticipation. Earlier releases
(v0.3.0 and below) used the popular names; after upgrading, state entries
saved under the old names are ignored (those axes restart from baseline) and
affectus feel rejects the old names.
Three alternative models ship built in: affectus init --model russell (2-axis
core affect), affectus init --model occ (22 OCC emotions derived from
appraisals via affectus appraise — see
examples/system-prompt-snippet-occ.md), and affectus init --model barrett
(constructed emotion: Russell core affect plus a persistent concept store of
past experiences retrieved via affectus recall and stored via
affectus remember — see examples/system-prompt-snippet-barrett.md).
v0.3 note: affectus no longer renders emotions as natural-language text.
It emits a one-line JSON object of all axes; the LLM is responsible for
reading the values relationally (per the Plutchik wheel) and modulating its
response accordingly. See examples/system-prompt-snippet.md for guidance.
Decay is symmetric across axes by default: no emotion lingers longer than another.
License
MIT