← Back to Plugins
Channels

Adaptive Tone

vishalnairv By vishalnairv 👁 18 views ▲ 0 votes

OpenClaw plugin that adapts the assistant's tone to context (time, channel, repetition, wellbeing, weather).

GitHub

Install

npm install
npm

Configuration Example

{
  "enabled": true,
  "time": { "enabled": true, "timezone": "Europe/Berlin" },
  "place": {
    "enabled": true,
    "professionalChannels": ["slack", "teams"],
    "casualChannels": ["whatsapp", "telegram"]
  },
  "repetition": { "enabled": true, "windowTurns": 6, "similarityThreshold": 0.8 },
  "wellbeing": { "enabled": true },
  "weather": { "enabled": true, "latitude": 52.52, "longitude": 13.41 },
  "guidanceOverrides": {
    "casual": "Keep it breezy and use first names."
  }
}

README

# Adaptive Tone — an OpenClaw plugin

Adjusts an OpenClaw assistant's **conversational tone** based on context:

- **Time of day** — calmer, more concise late at night.
- **Channel ("place")** — more formal in work channels, more relaxed in personal ones.
- **Repetition** — more patient, and re-explains differently, when you ask the same thing again.
- **Stated wellbeing** — gentler and lower-demand when you say you're unwell or having a hard time.
- **Weather** — subtly adapts tone to local weather conditions (sunny → cheerful, rainy → cozy, stormy → calm and reassuring).

It does this by registering one OpenClaw lifecycle hook (`before_prompt_build`) and
appending short tone guidance to the system prompt for that turn. **No OpenClaw core
code is modified.**

## What this is — and isn't

This is **tone steering, not emotion.** The underlying model has no feelings; OpenClaw
is an orchestration harness that calls a model. This plugin only changes the
*instructions* the model receives so its replies *read* warmer, calmer, more patient,
or more formal depending on context. It never changes the facts, the assistant's
accuracy, its capabilities, or its safety behaviour.

The "gentler when unwell" feature **softens tone only**. It explicitly does *not* provide
medical, crisis, or therapeutic advice, and it never overrides the model's own safety
guidance. It is not a mental-health tool.

The "weather-aware tone" feature uses the free [Open-Meteo API](https://open-meteo.com/)
to fetch current conditions. Results are cached for 15 minutes, and any fetch failure
is silently ignored (fail-open), so weather never blocks or breaks a reply.

## How it works

| Stage | Where (in OpenClaw) |
|---|---|
| Base system prompt is built | `src/agents/pi-embedded-runner/system-prompt.ts` |
| This plugin's hook runs and appends tone guidance | `before_prompt_build`, fired in `src/agents/pi-embedded-runner/run/attempt.ts` |

The hook resolves the current context to exactly one **tone state**
(priority: `gentle-care` › `patient-repeat`/`patient-light` › `quiet-latenight` ›
`professional`/`casual` › `neutral`) and returns `appendSystemContext`. Weather
guidance is layered additively on top of whichever tone state is active.

The guidance string is a pure function of the state, so OpenClaw's prompt cache stays
warm until the context category actually changes.

## Install

```bash
# from a local checkout (development)
openclaw plugins install --link /path/to/openclaw-adaptive-tone

# from git, once you've pushed it
openclaw plugins install git:github.com/<you>/openclaw-adaptive-tone

openclaw plugins enable adaptive-tone
openclaw gateway restart
```

Verify it loaded:

```bash
openclaw plugins inspect adaptive-tone --runtime --json
```

## Configure

Settings live under `plugins.entries.adaptive-tone.config`. All fields are optional;
sensible defaults apply. Example:

```jsonc
{
  "enabled": true,
  "time": { "enabled": true, "timezone": "Europe/Berlin" },
  "place": {
    "enabled": true,
    "professionalChannels": ["slack", "teams"],
    "casualChannels": ["whatsapp", "telegram"]
  },
  "repetition": { "enabled": true, "windowTurns": 6, "similarityThreshold": 0.8 },
  "wellbeing": { "enabled": true },
  "weather": { "enabled": true, "latitude": 52.52, "longitude": 13.41 },
  "guidanceOverrides": {
    "casual": "Keep it breezy and use first names."
  }
}
```

Notes:

- **Timezone:** the hook context does not currently expose the user's timezone, so set
  `time.timezone` (IANA, e.g. `Europe/Berlin`) for correct late-night detection.
  Without it, the Gateway host's local time is used.
- **Disabling an axis:** set e.g. `wellbeing.enabled: false` to turn off just that
  signal while keeping the others.
- **Weather:** defaults to Berlin (52.52, 13.41). Set your own latitude/longitude for
  accurate local weather. The weather API is rate-limited to one call per 15 minutes.
  Disable with `weather.enabled: false`.
- **Overrides** must stay static (no per-turn data) to preserve prompt caching.

## Weather conditions

The weather signal maps [WMO weather codes](https://open-meteo.com/en/docs#weathervariables)
and temperature into these conditions:

| Condition | Trigger | Tone effect |
|---|---|---|
| ☀️ Sunny | WMO code 0 (clear sky) | Slightly more cheerful and energetic |
| ☁️ Cloudy | WMO codes 1–3, 45, 48 | Calm, focused, and steady |
| 🌧️ Rainy | WMO codes 51–65, 80–82 | Cozy, quiet, and reflective |
| ❄️ Snowy | WMO codes 71–75, 85–86 | Warm, cozy, and comforting |
| ⛈️ Stormy | WMO codes 95–99 | Reassuring, stable, and calm |
| 🔥 Hot | Temperature > 30 °C | Light, cool, and brief |
| 🥶 Cold | Temperature < 5 °C | Warm and comforting |

Temperature extremes (hot/cold) take priority over weather codes.

## Develop

```bash
npm install
npm run typecheck
npm test
```

Logic lives in `src/` as pure, dependency-free functions; `index.ts` wires them into the
hook. Tests cover signal detection, state priority, cache-stable guidance, and weather
classification.

## Project structure

```
index.ts          — Plugin entry: registers the before_prompt_build hook
src/
  config.ts       — Config types + normalization (mirrors openclaw.plugin.json schema)
  guidance.ts     — Maps tone states and weather conditions to guidance text
  signals.ts      — Pure signal detectors (time, channel, repetition, wellbeing)
  states.ts       — Priority-ordered tone state resolution
  weather.ts      — Open-Meteo API client with 15-minute cache
test/
  signals.test.ts — Signal detection tests
  states.test.ts  — State priority and guidance tests
  weather.test.ts — Weather classification, guidance, and config tests
```

## License

MIT — see [LICENSE](LICENSE).
channels

Comments

Sign in to leave a comment

Loading comments...