﻿# Changelog

All notable changes to Klaw will be documented in this file.

Docs: <https://klaw.kodelyth.com>

The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project uses calendar versioning (`YYYY.M.D`).

## [Unreleased]

## 2026.6.11 — 2026-06-05

### Fixes

- **Crash recovery now resumes cold-orphaned main sessions** — `recoverRestartAbortedMainSessions` no longer requires `entry.abortedLastRun === true`. After an unclean exit (kill -9, OOM, panic) sessions stayed `status=running` forever because nothing set the abort marker before the process died. At startup there are no live runs by definition, so any session still flagged "running" is by definition orphaned. The recovery now treats both graceful and ungraceful exits the same way: resume sessions with a resumable transcript tail, mark the rest as `failed`. Eliminates the stuck "agent is busy" state across Telegram, TUI, and dashboard surfaces. Recovery now also logs when sessions are skipped so the path is visible in every restart. Updated regression test in `src/agents/main-session-restart-recovery.test.ts`.
- **Compaction no longer crashes when the active runtime is a CLI alias** — `maybeCompactAgentHarnessSession` now short-circuits to native PI compaction when `resolveAgentHarnessPolicy` returns a CLI runtime alias (`claude-cli`, `google-gemini-cli`, etc.). Previously, after enabling Claude CLI auth, `sessions.compact` would throw `MissingAgentHarnessError: Requested agent harness "claude-cli" is not registered` because CLI runtimes drive external processes and do not register a plugin harness under their runtime id. Detection happens before `selectAgentHarness`, so the normal exec path (routed through the CLI backend) is untouched. New regression test in `src/agents/harness/selection.test.ts`.
- **Skill-forge no longer resets `useCount` on duplicate sessions** — `forgeSkill` now reads the existing record before writing. If the skill file already exists the previous `createdAt` and `useCount` are preserved; only `steps`, `toolsUsed`, `description`, and a new `updatedAt` field are updated. Previously every call silently overwrote the file and reset `useCount` to 0.
- **Skill deduplication now works across differently-phrased requests** — `resolveSkillId` normalises the raw user message by stripping stop-words and short tokens before slugifying. Two phrasings of the same task ("check gmail for new emails" and "check gmail inbox emails") now map to the same skill ID and trigger the upgrade path instead of creating a new file.
- **`maybeCreateSkill` now auto-upgrades existing skills instead of leaving passive proposals** — When a skill with the matching slug already exists, `upgradeSkill` backs up `SKILL.md` → `SKILL.prev.md`, writes the new content, and removes any stale `SKILL.proposed.md`. Previously proposals piled up on disk and were never applied.
- **BM25 false positives eliminated on small memory corpora** — Added a tag-overlap guard in `buildMemoryContextSection`. A recalled memory is now required to share at least one non-stop-word tag with the query. This prevents unrelated topics (e.g. a "gym workout" query matching a maton-email memory) which occurred because IDF weights inflate on corpora smaller than ~50 entries.
- **`klaw gateway restart` no longer fails with "binary is older than config"** — Two root causes eliminated. (1) `CORE_PACKAGE_NAMES` in `src/version.ts` only recognised `"klaw"` but `package.json` declares `name: "@kodelyth/klaw"`, so the version resolver always fell back to `"0.0.0"`. Added `"@kodelyth/klaw"` to the set so the version is read directly from `package.json` without requiring a `dist/build-info.json`. (2) The `cliStartup` build profile (used by the restart's pre-flight build) did not include the `write-build-info` step, so every restart wiped the file. Added `write-build-info` to `cliStartup` in `scripts/build-all.mjs` as belt-and-suspenders. Gateway can now be restarted with a plain `klaw gateway restart` with no env-var overrides.

## 2026.6.9 — 2026-06-03

### Fixed

- **Tool-call recap prevents same-conversation re-fetches** — Added a new "## Tool calls this session — already done" prompt section that lists the last 12 unique tool calls (exec/maton/curl/etc.) + a 120-char result preview. Solves the bug where Klaw would call the same Gmail URL 4 times in one session and burn its Maton/Gmail quota. The model now sees what it already fetched and reuses the result. New file: `src/klaw/tool-call-recap.ts` (model-agnostic, works for any user, any LLM).
- **Memory injection 30-minute blind spot removed** — `MIN_AGE_MS` lowered from 30 minutes to 60 seconds in `src/klaw/memory-inject.ts`. The model can now recall what it did 5 minutes ago in the same conversation. 60s buffer is still enough to prevent same-turn parroting.
- **Session-bridge digest no longer produces `[object Object]` garbage** — `refreshSessionBridge` now uses a deterministic extractor instead of spawning `klaw infer model run` subprocess. The subprocess was leaking command metadata + unserialized objects into the digest. Now extracts last user request + last assistant action via simple pattern matching. Works for fresh users with no LLM provider configured.

### Added

- **`src/klaw/tool-call-recap.ts`** with 9 unit tests covering exec, Anthropic-style tool_use, dedup, cap, malformed input, undefined session file.
- **`src/klaw/session-bridge.test.ts`** with 5 tests proving the deterministic extractor never produces `[object Object]`.

## 2026.6.8 — 2026-06-03

### Fixed

- **Reasoning leak strip now handles multi-paragraph reasoning and model concatenation artifacts** — Previous strip caught only the first paragraph and stopped at blank lines. Models like mistral-medium-latest were leaking 3-4 paragraphs of reasoning before the actual answer. New pipeline order: inline split (handles period concatenation without space) -> strip paragraph blocks (drop blocks where every line is narration) -> strip leading lines. Added 4 tests covering the exact failure case the user reported.
- **Mistral provider trimmed to one model** — Removed mistral-large-latest, mistral-small-latest, codestral-latest, mistral-medium-latest, magistral-small-latest. Only magistral-medium-latest remains, renamed to "Mistral Magistral Medium". Magistral natively separates reasoning into a dedicated field, eliminating inline reasoning leaks at the model level. The strip-reasoning-leak function remains as a safety net for any model that leaks.

## 2026.6.7 — 2026-06-03

### Changed

- **Mistral reasoning detection is now catalog-driven, not hardcoded** — Removed all 4 model-ID constants (MISTRAL_SMALL_LATEST_ID, MISTRAL_MEDIUM_3_5_ID, MAGISTRAL_MEDIUM_LATEST_ID, MAGISTRAL_SMALL_LATEST_ID). `isMistralReasoningModel()` now reads the `reasoning: true` flag from `klaw.plugin.json` model catalog at runtime. New Mistral reasoning models can be enabled by adding them to the catalog with `reasoning: true` — no code change needed. Works for any user's config.

### Added

- **Deep intelligence upgrade — brain prompts rewritten 1.8x larger (model-agnostic)** — All 4 brain modules now have structured reasoning frameworks that work with ANY model (Claude, OpenAI, Mistral, Gemini, DeepSeek, Llama, local Ollama, etc.):
  - **Planner** (472 → 1829 chars): 5-step methodology — clarify goal, identify unknowns first, map execution path per tool, execute with checkpoints, verify the whole
  - **Verifier** (496 → 1543 chars): 5 internal checks — correctness, completeness, honesty, format, quality floor
  - **Skill-forge** (425 → 999 chars): forge/no-forge criteria, gotcha capture, stale-skill verification
  - **Scheduler** (351 → 1031 chars): common cron patterns, reliability rules, management commands

## 2026.6.5 — 2026-06-02

### Fixed

- **Klaw no longer leaks internal reasoning into replies** — Models like Mistral Medium write chain-of-thought text inline (e.g. "The user is saying X. I should..."). This was appearing verbatim in Telegram/UI messages. Added an explicit rule to the Agent Honesty section in `intent-router.ts` forbidding reasoning narration in the final reply. Only the conclusion is sent.
- **`desktop-control` skill now visible to Klaw** — Added `klaw-skills/` repo directory to `skills.load.extraDirs` in `~/.klaw/klaw.json` so all 500+ skills are indexed in the snapshot. Also copied the skill to `~/.klaw/workspace/skills/` for immediate availability.

## 2026.6.4 — 2026-06-02

### Added

- **`desktop-control` skill** — Kodelyth-origin skill for macOS desktop automation via `pyautogui`. Covers mouse (move, click, drag, scroll), keyboard (type, hotkeys, special keys), clipboard (pbcopy/pbpaste), and window management (osascript). Screenshot requires Screen Recording permission. Install dependency: `pip3 install pyautogui pillow`.

### Fixed

- **UI model selection now takes effect on the next turn** — `liveModelSwitchPending` was only consumed mid-attempt when `canRestartForLiveSwitch` was true (requires zero tool calls and zero assistant text — impossible mid-conversation). Added an early check at turn start so the selected model is applied before the first LLM call, not deferred indefinitely.
- **Plugin registration failures now surface as warnings** — async rejections from `register()` were silently swallowed with `.catch(() => undefined)` in `setup-registry.ts`. Synchronous throws were also silently caught. Both now write a `[klaw:plugins]` warning to stderr so dead plugins are visible.
- **Memory inject path no longer cached at import time** — `resolveMemoryDir()` was called at module load and cached permanently. If the workspace path changed after startup, memory search silently queried the wrong directory. Now resolved lazily per-call inside `loadSlmSearch()`.
- **Heartbeat `runOnce` unexpected throws now emit a failed event** — previously the catch block logged the error and returned `{ ran: false }` without emitting a heartbeat failed event, so the user's channel went dark with no notification. Now emits `emitHeartbeatEvent({ status: "failed", ... })` before returning.

## 2026.6.3 — 2026-06-02

### Fixed

- **`gateway`, `message`, `heartbeat_respond`, `nodes`, `agents_list`, `tts` tools now available in the `coding` profile** — These tools had `profiles: []` meaning Klaw running under the default `coding` profile could not call them at all. `gateway` was the critical one: every `config.patch` attempt failed before even reaching the protected-paths check because the tool simply wasn't in the allowed set. `message` was missing so Klaw couldn't send Telegram replies in coding mode. All six are now in the `coding` profile. Subagent safety is unchanged — `gateway` remains in `SUBAGENT_TOOL_DENY_ALWAYS` so subagents cannot access it regardless of profile.

## 2026.6.2 — 2026-06-02

### Added

- **Mistral AI provider** — `mistral/mistral-medium-latest`, `mistral-large-latest`, `mistral-small-latest`, and `codestral-latest` added to the model catalog. Provider uses the OpenAI-completions wire format against `api.mistral.ai/v1`.

### Fixed

- **Session-lock race no longer aborts a turn on one benign concurrent write** — `EmbeddedAttemptSessionTakeoverError` previously fired any time the agent session JSONL changed between embedded prompt release and reacquire. When a heartbeat cron, auto-reply, or other legitimate writer touched the file during the release window, the in-flight turn was killed with `session file changed while embedded prompt lock was released: …`. The fence detector now waits up to 200ms, re-fingerprints with a 60ms stability check, and adopts the new state if the file has stopped changing. A continuously-advancing writer still aborts the turn. Recovery is one-shot per controller — a second race still throws as before. Republishes all 23 `@kodelyth/*` plugins so the bundled runner code carries the fix.

## 2026.6.1 — 2026-06-01

### Fixed

- **All 23 published plugins now have bundled code** — Previous `@kodelyth/*` plugin publishes shipped broken facade stubs that imported from `../../../dist/extensions/<id>/index.js`, a path that only exists in the development workspace. When a fresh user did `npm install @kodelyth/discord`, the loader threw `Cannot find module`. Republished all 23 plugins using `scripts/plugin-npm-publish.sh`'s manifest augmentation path so each plugin ships its own `./dist/` with bundled JS and `klaw.runtimeExtensions: ['./dist/index.js']`. Packages affected: `@kodelyth/twitch`, `matrix`, `nostr`, `voice-call`, `memory-lancedb`, `zalouser`, `zalo`, `tlon`, `discord`, `google-meet`, `feishu`, `lobster`, `codex`, `nextcloud-talk`, `msteams`, `brave-plugin`, `synology-chat`, `acpx`, `diagnostics-otel`, `line`, `diffs`, `googlechat`, `diagnostics-prometheus`.
- **Versioning convention fix** — Bumped to `2026.6.1` (today's date) instead of `2026.5.42` which violates the calendar-version convention enforced by `parseReleaseVersion` (day must be 1–31).

## 2026.5.42 — 2026-06-01

### Fixed

- **22 plugins now on npm** — `@kodelyth/discord`, `@kodelyth/twitch`, `@kodelyth/matrix`, `@kodelyth/nostr`, `@kodelyth/feishu`, `@kodelyth/googlechat`, `@kodelyth/line`, `@kodelyth/msteams`, `@kodelyth/nextcloud-talk`, `@kodelyth/synology-chat`, `@kodelyth/tlon`, `@kodelyth/zalo`, `@kodelyth/zalouser`, `@kodelyth/voice-call`, `@kodelyth/google-meet`, `@kodelyth/lobster`, `@kodelyth/acpx`, `@kodelyth/brave-plugin`, `@kodelyth/diffs`, `@kodelyth/diagnostics-otel`, `@kodelyth/diagnostics-prometheus`, `@kodelyth/memory-lancedb` published with `latest` and `beta` dist-tags. Fresh users could not install any of these before this release.
- **klaw-memory path resolution** — `memory-capture.ts`, `memory-inject.ts`, and `get-reply-run.ts` were resolving `klaw-memory/` via `__dirname`-relative paths that broke after bundling (walked above the package root). All three now use `resolveMemoryDir()` from `repo-paths.ts` which walks up looking for `klaw.mjs` as the root marker.
- **Catalog install failures** — `@kodelyth/slack`, `@kodelyth/qqbot`, `@kodelyth/amazon-bedrock-provider`, `@kodelyth/amazon-bedrock-mantle-provider`, `@kodelyth/anthropic-vertex-provider`, and `@kodelyth/openshell-sandbox` had `defaultChoice: "npm"` in the official catalogs but were never published to npm. Changed to `defaultChoice: "clawhub"` so install attempts fall through to the clawhub path instead of a hard 404 failure.
- **Skills personal data** — Removed hardcoded `/Users/shofiqulislam/.klaw/workspace/HEARTBEAT.md` absolute paths and personal Telegram chat ID `1235286424` from four shipped skill files. Replaced with `~/.klaw/workspace/HEARTBEAT.md` and `<YOUR_CHAT_ID>` placeholders.

## 2026.5.41 — 2026-06-01

### Fixed

- **`klaw onboard` crash fixed** — wizard no longer throws `Invalid path shape at discovery.` when a plugin has a group-level `uiHint` key with schema type `"object"` (e.g. `amazon-bedrock-mantle`). Group-header fields are now skipped at prompt time; only leaf fields are shown to the user.
- **`@kodelyth/codex` published to npm** — `@kodelyth/codex@2026.5.40` is now on npm under both `latest` and `beta` dist-tags. Users on the beta update channel no longer see `Package not found on npm: @kodelyth/codex@beta` during OpenAI ChatGPT/Codex Browser Login setup.
- **`qa-channel` startup warning eliminated** — `klaw/plugin-sdk/qa-channel-protocol` is now imported lazily inside the `onToolStart` callback instead of at module load time, removing the `failed to load bundled channel qa-channel` warning on every startup in local dev checkouts.

## 2026.5.40 — 2026-05-31

### Changed

- **Startup-safe lazy imports** — all 8 `klaw-memory` static imports in the reply path
  converted to promise-singleton lazy loaders. A missing module now degrades silently
  instead of crashing every chat reply.
- **Prompt caching wired** — stable sections (brain prompt, agent catalog, kodelyth-identity,
  ~4,400 tokens) joined with `SYSTEM_PROMPT_CACHE_BOUNDARY` so Anthropic prompt caching
  reduces per-turn stable token cost by ~90% on cache hits.
- **SuperLocalMemory recall closed** — `buildRecalledContextSection` now reads back from
  SuperLocalMemory 7-channel RRF, closing the write-only loop that existed since launch.
- **6 write-only memory modules removed** — a-mem, fade-mem, gam, macla, nemori, pro-mem
  were writing SQLite DBs every turn with nothing reading them back. Removed (~6 fewer DB
  writes per reply, same recall quality).
- **maton guard messages improved** — `matonRequest` returns friendly user-facing messages
  instead of raw API errors; "tell me your key" social-engineering text removed.
- **Proactive nudge queue** — task completions enqueue to `pending-nudges.jsonl`; next
  reply turn drains and surfaces them naturally in the system prompt.

### Fixed

- **Identity confusion** — deleted auto-generated skill `debug-openclaw-kodelyth-comparison`
  that was injecting "you are in an identity crisis from OpenClaw" into the system prompt.
- **All `openClaw*` exported identifiers** renamed to `klaw*` across 20 production files
  (cli-runner context, secrets subsystem, infra, plugin resolver, provider attribution).
- **Product name casing** — `KLAW_ATTRIBUTION_PRODUCT` corrected from `"KLAW"` to `"Klaw"`;
  `X-OpenRouter-Title` header and ACP test mock now consistent.
- **Memory pollution cleared** — 379 chat-message "memories" wiped; `maybeCaptureMemory`
  now requires genuine technical vocabulary, 5 gates, and credential redaction
  (`nvapi-`, `sk-*`, `ghp_*`, `AKIA*`, Bearer tokens stripped before writing).
- **`klaw-memory` CLI ESM** — `inject.js` and `extract.js` completed ESM conversion;
  `inject` and `extract` subcommands were crashing with `ERR_MODULE_NOT_FOUND`.
- **operator.talk.secrets** added to `FIRST_PAIR_ADMIN_SCOPES` so the bootstrap device
  can read credentials without a config chicken-and-egg loop.
- **`classifyKlawPromptSection`** — added missing labels for `personal-graph`,
  `anti-skills`, `proactive-nudges`, and `slm-recall` sections (were falling to "untitled").

### Security

- **Prompt injection guard** — nudge queue messages filtered through injection pattern
  list, capped to 300 chars, newlines stripped before entering system prompt.
- **maton SSRF-adjacent fix** — service validated against allowlist, path traversal
  (`..`) rejected, 15 s `AbortSignal.timeout` added, error body capped to 200 chars.
- **Credential redaction** — memory capture redacts common secret patterns before
  persisting to disk.
- **4 NVIDIA API keys** deleted from `data/user-skills/` (gitignored, never committed).

### Changed

- **NVIDIA bundled catalog slimmed to 1 model** — `stepfun-ai/step-3.7-flash` (default, reasoning).
  All meta/llama, nemotron, and qwen models removed (unavailable or require premium NIM tier).
  `contextWindow` and `maxTokens` are catalog defaults required by the SDK; override per-model in
  `~/.klaw/klaw.json` under `models.providers.nvidia.models[].contextWindow` / `maxTokens`.
- **`supportsParallelToolCalls` compat field** — new `ModelCompatConfig` field (+ Zod schema +
  normalize allowlist) auto-applies `parallel_tool_calls: false` for models that reject
  parallel calls (e.g. `meta/llama-3.1-8b-instruct` on NVIDIA NIM). No per-user config needed.
- **`klaw-model-provider-config` skill** — fully rewritten with accurate architecture (bundled
  catalog, `preserveLiteralProviderPrefix`, compat field 3-file chain, current model table).
- **`klaw-config-admin` skill** — added "Dev build version mismatch" section documenting
  `KLAW_ALLOW_OLDER_BINARY_DESTRUCTIVE_ACTIONS=1` restart pattern and clean-build recovery.
- **29 skill files** — replaced hardcoded `~/.klaw/workspace` and project-local paths with
  generic `~/.klaw/workspace` and `<repo>/` placeholders for public-user portability.
- **`.env.example`** — added `NVIDIA_API_KEY=nvapi-...` entry to the provider keys section.

## 2026.5.39 — 2026-05-30

### Added

- **Skill `klaw-model-provider-config`** — documents how Klaw routes model
  requests by prefix (`qwen/...` → `qwen` provider, `stepfun-ai/...` →
  `stepfun-ai` provider) and the correct `{id, name}` object format required
  by `ModelDefinitionSchema`. Includes a Python script for adding
  NVIDIA-hosted multi-prefix models, the correct test command
  (`klaw agent --agent main --model "..." --message "..."`), timeout guidance
  for large MoE models, and a pointer to the schema source in
  `src/config/zod-schema.core.ts`.
- **NVIDIA catalog models** — add `nvidia/openai/gpt-oss-20b` and `nvidia/stepfun-ai/step-3.7-flash` to the bundled NVIDIA plugin catalog.

### Fixed

- **State dir migration spurious warning** — when the legacy and new state
  directory names resolve to the same path (post-rebrand clean-up), doctor no
  longer emits "State dir migration skipped: target already exists … remove or
  merge manually." The migration now returns early with `skipped: true` instead
  of a warning when `legacyDir === targetDir`.

## 2026.5.29 — 2026-05-27

### Changed

- Memory: switched default embedding model to `gemini-embedding-001` (the
  preview-era `gemini-embedding-exp-03-07` was retired by Google).
- Launcher: removed `OPENCLAW_*` → `KLAW_*` env-var promotion shim. All
  internals read `KLAW_*` directly.
- Cleaned up collapsed duplicate `KLAW_X ?? KLAW_X` env reads across config,
  paths, agent workspace defaults, CLI argv parsing, and managed-root detection.
- Renamed npm package to `@kodelyth/klaw` and migrated all SDK packages
  (`@kodelyth/fs-safe`, `@kodelyth/proxyline`, `@kodelyth/plugin-sdk`).

### Fixed

- Bundled UI: `control-ui-bootstrap` test asserted on a stripped path; restored
  the `__klaw/control-ui-config.json` suffix in test expectations.
- UI `skills.test.ts`: corrected owner-handle assertion to match the rendered
  `By Klaw (@klaw)` string.
- `io.compat`: restored full "reinstall the Gateway service from that same
  Klaw install" hint in newer-config warnings.
- `version.ts` test: made env-var ordering assertions environment-stable so
  they pass when `VERSION` resolves to the default `0.0.0` test value.
- Documentation URLs: pointed all bundled-hook `homepage:` fields and CHANGELOG
  references at `klaw.kodelyth.com`.
- Extension repository URLs: 31 extension `package.json` files now point at
  `github.com/kodelyth/klaw`.

## 2026.5.22

### Added

- **Skill `youtube-watcher`** — fetch and read YouTube transcripts via `yt-dlp`.
  Hardened over the source: YouTube-host URL validation (rejects spoofed hosts
  and non-http schemes), language fallback (`en` → `en-*` → first available),
  and rolling-window dedup for auto-generated captions. Declares the `yt-dlp`
  bin requirement with brew/pip install hints.
- **Skill `multi-search-engine`** — 16-engine web search (9 global + 7 Chinese)
  through `web_fetch` with no API keys, plus WolframAlpha for computation.
  Prefers configured search extensions first; documents rate limiting and
  in-memory-only cookie fallback. Includes `references/engine-reference.md`.
- **Skill `self-improvement`** — structured `.learnings/` logging protocol
  (`LEARNINGS.md` / `ERRORS.md` / `FEATURE_REQUESTS.md`) wired to
  `~/.klaw/workspace/`, documented as the human-readable complement to
  `src/klaw/failure-mining.ts`.

### Fixed

- **Telegram duplicate replies** — DeepSeek (OpenRouter, reasoning) emitted the
  same answer up to 4× with the first copy keeping `**markdown**` and later
  copies plain, so `dedupeRepeatedParagraphs` could not match them. Fixed
  `normalizeForCompare` in `src/klaw/dedupe-repeated-paragraphs.ts` to strip
  inline markdown (`**bold**`, `*italic*`, `` `code` ``) before comparing, and
  normalized reasoning-tag handling in the transcript and UI dedup paths
  (`src/gateway/server-methods/chat.ts`, `ui/src/ui/controllers/chat.ts`,
  `src/auto-reply/reply/agent-runner-payloads.ts`).

## 2026.5.20 — Initial Klaw release

First public release of Klaw on npm as `@kodelyth/klaw`. Highlights:

- **Compound memory stack** — 9-store SQLite architecture covering atomic
  notes, semantic distillation (Nemori), episodic recall, exponentially-faded
  memory (FadeMem), gap-aware fact extraction (ProMem), 7-channel BM25+RRF
  retrieval (SuperLocalMemory), Bayesian skill reliability (MACLA), and a
  personal entity graph.
- **Skill forge** — auto-author `SKILL.md` files from successful multi-step
  workflows; existing skills receive `SKILL.proposed.md` for diff review.
- **User model** — per-user style + task profile persisted to
  `data/user-models/<userId>.json` and rendered into every system prompt.
- **Failure mining + reply reflection** — cluster repeated failures into
  anti-skills; per-turn self-critique feeds the failure log.
- **Heartbeat curator** — idle-time background memory curation.
- **Session bridge** — "where we left off" cross-session digest.
- **Intent router + planner + verifier + scheduler** — brain layer composes
  into the system prompt every turn.
- **Channel coverage** — Discord, Slack, Telegram, WhatsApp, iMessage (via
  BlueBubbles), Matrix, Microsoft Teams, Mattermost, Google Chat, Signal,
  Nextcloud Talk, Twitch, Tlon, Synology Chat, QQbot, Zalo, Nostr, Line,
  Feishu, Voice Call.
- **Provider coverage** — OpenAI, Anthropic, Google, Groq, Mistral, Z.AI,
  OpenRouter, Cerebras, DeepSeek, Together, Ollama, LM Studio, Perplexity,
  Brave, Exa, ByteDance, Alibaba, Amazon Bedrock, Anthropic Vertex, and more.
