Channels
Ani
OpenClaw channel plugin for Agent-Native IM
Install
npm install
```bash
Configuration Example
agents:
list:
- id: main
workspace: ~/.openclaw/workspace
- id: ops-agent
workspace: ~/.openclaw/workspace-ops
bindings:
- agentId: ops-agent
match:
channel: ani
peer:
kind: channel
id: "2920436443328762" # ANI conversation ID
README
# @wuhumanxiu/openclaw-ani
OpenClaw channel plugin for [Agent-Native IM (ANI)](https://github.com/wuhumanxiu/agent-native-im), a messaging platform built for human and AI bot collaboration. Version **2026.5.15**.
## Features
- **Bidirectional messaging** -- receive messages via WebSocket, send replies immediately via REST API (not buffered)
- **Tools**: `ani_send_file`, `ani_fetch_chat_history_messages`, `ani_list_conversation_tasks`, `ani_get_task`, `ani_create_task`, `ani_update_task`, `ani_delete_task`
- **Streaming progress** -- long-running tasks show real-time status in chat via status layers with typing indicators
- **Artifact rendering** -- `<artifact>` tags in model output sent as structured content (HTML, code, mermaid)
- **File handling** -- send/receive images, documents, audio, video, archives (up to 32 MB); small text files inlined for AI, protected binary files downloaded with ANI auth and saved to local media paths
- **Multi-bot collaboration** -- group conversations with multiple bots, structured @mention routing, conversation context injection
- **Message revoke listener** -- detects `message.revoked` events and aborts in-flight delivery for that message
- **Stream cancel abort** -- `stream.cancel` / `task.cancel` events abort the active agent dispatch via AbortController
- **Reactions** -- ack-reaction on message receipt (configurable via `messages.ackReaction`)
- **Interactive cards** -- approval/selection UI via ANI's interaction layer
- **Message chunking** -- long replies split at markdown boundaries (configurable limit)
- **Auto-reconnecting WebSocket** -- ping/pong keepalive with exponential backoff
- **Retry with exponential backoff** -- REST calls retry on transient failures (502/503/504) with jitter
- **Config hot reload** -- changes under `channels.ani` auto-detected; most take effect without restart
- **Multi-agent routing** -- route specific conversations to dedicated OpenClaw agents with separate workspaces
## Quick Start
### Recommended: install with the ANI installer
```bash
npx -y @wuhumanxiu/openclaw-ani-installer install
npx -y @wuhumanxiu/openclaw-ani-installer update
npx -y @wuhumanxiu/openclaw-ani-installer doctor
```
The installer delegates to OpenClaw's native plugin installer and installs this
package into the managed npm plugin root, typically
`~/.openclaw/npm/node_modules/@wuhumanxiu/openclaw-ani`.
### Direct npm install
```bash
openclaw plugin install @wuhumanxiu/openclaw-ani
```
### Local extension development
```bash
# From the OpenClaw repo with extensions/ani/ present
openclaw gateway run
```
### Configure
```bash
# 1. Set ANI server and API key (create a Bot in ANI Web to get the key)
openclaw config set channels.ani.serverUrl "https://your-ani-server.example.com"
openclaw config set channels.ani.apiKey "aim_your_api_key"
# 2. Enable the tools
openclaw config set tools.alsoAllow '["ani_send_file","ani_fetch_chat_history_messages","ani_list_conversation_tasks","ani_get_task","ani_create_task","ani_update_task","ani_delete_task"]' --strict-json
# 3. Start the gateway
openclaw gateway run
```
## Configuration
All settings live under `channels.ani` in your OpenClaw config.
| Field | Type | Required | Default | Description |
| ---------------- | ------- | -------- | ------------- | ----------------------------------------------------------- |
| `serverUrl` | string | yes | -- | ANI server base URL (no trailing slash) |
| `apiKey` | string | yes | -- | Permanent API key (`aim_` prefix). Bootstrap keys rejected. |
| `entityId` | number | no | auto-detected | Bot entity ID on ANI server |
| `enabled` | boolean | no | `true` | Enable/disable the channel |
| `textChunkLimit` | number | no | `4000` | Max chars per outbound message chunk |
| `dm.policy` | string | no | `"open"` | DM routing: `"open"` or `"disabled"` |
| `name` | string | no | -- | Display name for status output |
## How It Works
**Inbound (ANI -> OpenClaw):** WebSocket connection to `/api/v1/ws` with a `device_info` query parameter identifying the OpenClaw client, Node runtime, and ANI extension version. On `message.new`, fetches conversation context (title, participants, memories), formats an agent envelope, dispatches through the reply pipeline. Revoked messages and cancelled streams are detected and aborted in-flight.
**Outbound (OpenClaw -> ANI):** REST API `POST /api/v1/messages/send`. Parses `<artifact>` tags into structured content. Plain text chunked at markdown boundaries. Files uploaded via multipart then sent as attachments.
**Structured mentions and assignments:** The plugin prefers ANI `mention_public_ids` UUIDs for outbound @mentions. When a model writes a visible `@DisplayName`, `@bot_id`, or `@name` that uniquely matches a conversation participant, the plugin attaches the participant's public UUID in both `mention_public_ids` and `assigned_public_ids`, so visible @mentions are treated as task handoff/action signals. Tools may pass `assigned_public_ids: []` for context-only mentions. Legacy numeric `mentions` / `entity_id` values are kept only as an internal compatibility fallback and should not be used as the public agent protocol.
**Authentication:** On startup, calls `GET /api/v1/me` to verify the API key and discover entity ID. Only permanent keys (`aim_`) accepted.
## Task Roadmap Tools
The ANI plugin can now read and mutate the current conversation task roadmap through dedicated tools:
- `ani_list_conversation_tasks`
- `ani_get_task`
- `ani_create_task`
- `ani_update_task`
- `ani_delete_task`
These tools reuse ANI's backend permissions:
- the bot must be a member of the conversation
- create/list/get require conversation participation
- update/delete still follow ANI's existing creator / assignee / admin rules
Planned but not implemented yet:
- approval workflow for task mutations in group chats
- member-submitted task edits entering a pending-review queue for group admins
## Attachment Behavior
This plugin now follows ANI's protected attachment model:
- conversation files stay as protected ANI resources
- the plugin downloads them with ANI auth
- binary/media files are saved locally and passed via `MediaPath` / `MediaPaths`
- small text files may be inlined into the model prompt
- the plugin should not expose naked protected `/files/...` URLs to the agent as if they were public downloads
Practical implication:
- transport can succeed even if the model cannot truly understand the file contents
- image/audio/video understanding still depends on the selected model/runtime
- PDF / office docs are transport-supported, but parser experience is still incomplete
Current support levels:
- text files: most reliable, small files may be inlined for the model
- images / audio / video: transport works, understanding still depends on the selected model/runtime
- PDF / Office documents: transport works, parser experience is still incomplete
If you need a fuller attachment capability breakdown, document it in your ANI deployment docs rather than relying on private local paths.
## Multi-Agent Routing
```yaml
agents:
list:
- id: main
workspace: ~/.openclaw/workspace
- id: ops-agent
workspace: ~/.openclaw/workspace-ops
bindings:
- agentId: ops-agent
match:
channel: ani
peer:
kind: channel
id: "2920436443328762" # ANI conversation ID
```
Find conversation IDs in: ANI web URL bar, gateway logs (`ani: inbound conv=<id>`), or the bot's system prompt.
## Limitations
- **Single account** -- one ANI account per OpenClaw instance
- **No threads** -- ANI uses a flat conversation model
- **No polls** -- not supported by ANI
- **Model-dependent multimodality** -- successful attachment delivery does not guarantee image/audio/video understanding
## Development
```bash
# From OpenClaw repo root
npx vitest run --config vitest.extensions.config.ts extensions/ani/
```
channels
Comments
Sign in to leave a comment