@mutirolabs/openclaw-brain 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,401 @@
1
+ # Use OpenClaw as the Brain for Your Mutiro Agent
2
+
3
+ Copy the prompt below into your AI assistant (Claude, Cursor, Windsurf, or similar) and it will walk you through pointing [OpenClaw](https://openclaw.ai) at a [Mutiro](https://mutiro.com) agent through `chatbridge`. Mutiro stays the messaging platform; OpenClaw becomes the brain.
4
+
5
+ ## The Prompt
6
+
7
+ ````
8
+ You are helping me run an existing Mutiro agent with OpenClaw as its brain over `chatbridge`. Mutiro keeps the agent identity, connectivity, messaging, auth, and media plumbing. OpenClaw becomes the thinking layer and drives outbound replies through the bridge.
9
+
10
+ Walk me through this step by step. Be proactive — run commands, check outputs, and make smart decisions based on what you find. Don't ask me things you can figure out by running a command. Only pause to ask when you genuinely need my input (like which LLM provider to use or what personality I want). When you need my input, ask me directly and wait for my response.
11
+
12
+ **Important:** Both CLIs have extensive built-in help. Use `mutiro --help`, `openclaw --help`, and their `<command> --help` variants. Check the CLI help first rather than guessing.
13
+
14
+ ---
15
+
16
+ ### Step 1: Make Sure a Mutiro Agent Exists
17
+
18
+ This guide assumes I already have a working Mutiro agent directory. If I don't, stop and point me at the Mutiro create-agent guide first:
19
+
20
+ > https://www.mutiro.com/docs/guides/create-agent.md
21
+
22
+ Check what's already set up:
23
+
24
+ ```bash
25
+ mutiro auth whoami
26
+ mutiro agents list
27
+ ```
28
+
29
+ If either fails, walk me through that guide first and come back here.
30
+
31
+ Once I have an agent, ask me which one I want to wire into OpenClaw, then confirm the agent directory path. The agent directory is the folder containing `.mutiro-agent.yaml`.
32
+
33
+ Record the absolute path — every later step uses it.
34
+
35
+ ---
36
+
37
+ ### Step 2: Stop the Built-in Mutiro Brain
38
+
39
+ **Do not run the built-in Mutiro brain and OpenClaw against the same agent at the same time.** Two brains on one agent will fight over the same conversations.
40
+
41
+ If Mutiro's built-in brain is currently running for that agent, stop it:
42
+
43
+ ```bash
44
+ # Inside the agent directory
45
+ cd /path/to/agent-directory
46
+ pkill -f "mutiro agent run" || true
47
+ # Or, if you launched it with `mutiro start`, stop that process.
48
+ ```
49
+
50
+ Verify nothing is holding the agent:
51
+
52
+ ```bash
53
+ mutiro agent doctor
54
+ ```
55
+
56
+ ---
57
+
58
+ ### Step 3: Install the OpenClaw CLI
59
+
60
+ Check if it's already installed:
61
+
62
+ ```bash
63
+ openclaw --version
64
+ ```
65
+
66
+ If not found, install it:
67
+
68
+ ```bash
69
+ curl -fsSL https://openclaw.ai/install.sh | bash
70
+ ```
71
+
72
+ Or, if I already use npm globally:
73
+
74
+ ```bash
75
+ npm i -g openclaw@latest
76
+ ```
77
+
78
+ Verify before continuing:
79
+
80
+ ```bash
81
+ openclaw --version
82
+ openclaw doctor
83
+ ```
84
+
85
+ ---
86
+
87
+ ### Step 4: Install the openclaw-brain Plugin
88
+
89
+ This plugin is the piece that lets OpenClaw speak Mutiro's `chatbridge`. It spawns `mutiro agent host --mode=bridge` as a subprocess and translates NDJSON envelopes into OpenClaw inbound messages and outbound send/react/forward/voice/card/forward calls.
90
+
91
+ Install from the published package:
92
+
93
+ ```bash
94
+ openclaw plugins install --dangerously-force-unsafe-install @mutirolabs/openclaw-brain
95
+ ```
96
+
97
+ Or clone and install from source while iterating:
98
+
99
+ ```bash
100
+ git clone https://github.com/mutirolabs/openclaw-brain ~/src/openclaw-brain
101
+ cd ~/src/openclaw-brain
102
+ # Skip node_modules — OpenClaw's install scanner walks the source tree and
103
+ # caps at 10k directories. Run `npm install` again later if you want local
104
+ # typecheck.
105
+ openclaw plugins install --dangerously-force-unsafe-install "file:$(pwd)"
106
+ ```
107
+
108
+ **About `--dangerously-force-unsafe-install`**: this plugin legitimately
109
+ spawns `mutiro agent host --mode=bridge` as a subprocess — that is the
110
+ entire `chatbridge` adapter. OpenClaw's install scanner correctly flags any
111
+ plugin that uses `child_process` as sensitive and requires this flag as an
112
+ explicit acknowledgement. Before you pass it, confirm you are installing
113
+ from the signed [`mutirolabs/openclaw-brain`](https://github.com/mutirolabs/openclaw-brain)
114
+ source (or the `@mutirolabs/openclaw-brain` npm package). Review the
115
+ `spawn` call at [`src/bridge-client.ts`](https://github.com/mutirolabs/openclaw-brain/blob/main/src/bridge-client.ts)
116
+ if you want to see exactly what the plugin executes.
117
+
118
+ Verify OpenClaw sees the channel:
119
+
120
+ ```bash
121
+ openclaw plugins list | grep -i mutiro
122
+ openclaw channels list | grep -i mutiro
123
+ ```
124
+
125
+ ---
126
+
127
+ ### Step 5: Point OpenClaw at the Mutiro Agent Directory
128
+
129
+ **Preferred — interactive wizard.** Run the bare `channels add` command (no
130
+ `--channel` flag; passing one skips the wizard and falls through to the
131
+ non-interactive adapter):
132
+
133
+ ```bash
134
+ openclaw channels add
135
+ ```
136
+
137
+ Pick `mutiro` from the list. The wizard detects the `mutiro` CLI, asks for
138
+ the agent directory, validates it, runs `mutiro auth whoami`, and writes the
139
+ config.
140
+
141
+ **Non-interactive alternative.** Use the single-account shorthand if I only
142
+ have one Mutiro agent:
143
+
144
+ ```bash
145
+ openclaw config set channels.mutiro.accounts.default.agentDir /absolute/path/to/agent-directory
146
+ openclaw config set channels.mutiro.enabled true --strict-json
147
+ ```
148
+
149
+ For multiple Mutiro agents, use named accounts:
150
+
151
+ ```bash
152
+ openclaw config set channels.mutiro.accounts.coach.agentDir /path/to/coach-agent
153
+ openclaw config set channels.mutiro.accounts.assistant.agentDir /path/to/assistant-agent
154
+ ```
155
+
156
+ The plugin will spawn one `mutiro agent host --mode=bridge` process per configured account and keep it alive across conversations.
157
+
158
+ Confirm the config was written:
159
+
160
+ ```bash
161
+ openclaw config get channels.mutiro
162
+ ```
163
+
164
+ ---
165
+
166
+ ### Step 6: Pick an LLM Provider for OpenClaw
167
+
168
+ OpenClaw runs its own agent with its own system prompt, tools, and provider. The Mutiro `.mutiro-agent.yaml` provider settings are ignored while OpenClaw is the brain — Mutiro is just the messaging surface.
169
+
170
+ Check what provider keys are already in my environment:
171
+
172
+ ```bash
173
+ echo "ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:+set}" \
174
+ "OPENAI_API_KEY=${OPENAI_API_KEY:+set}" \
175
+ "GEMINI_API_KEY=${GEMINI_API_KEY:+set}" \
176
+ "GOOGLE_API_KEY=${GOOGLE_API_KEY:+set}"
177
+ ```
178
+
179
+ If one is set, suggest using that provider. Otherwise ask:
180
+
181
+ | Provider | Best for | Env var |
182
+ |----------|----------|---------|
183
+ | Anthropic Claude | Reasoning, coding, careful tool use | `ANTHROPIC_API_KEY` |
184
+ | OpenAI | GPT models, broad ecosystem | `OPENAI_API_KEY` |
185
+ | Google Gemini | Fast, good free tier | `GEMINI_API_KEY` |
186
+ | Ollama | Local/private | (no key) |
187
+ | LM Studio | Local/private, GUI | (no key) |
188
+
189
+ Configure the default model with whatever OpenClaw expects for that provider (check `openclaw models --help`). For example:
190
+
191
+ ```bash
192
+ openclaw models auth login --provider anthropic
193
+ openclaw models set-default anthropic/claude-opus-4-7
194
+ ```
195
+
196
+ If the provider requires no auth (Ollama, LM Studio), point OpenClaw at the local endpoint with `openclaw models` commands and skip the login step.
197
+
198
+ ---
199
+
200
+ ### Step 7: Write the Agent Instructions (OpenClaw Side)
201
+
202
+ OpenClaw's agent is configured through OpenClaw — not through `.mutiro-agent.yaml`. Its system prompt shapes how the brain thinks, what tools it reaches for, and how it speaks back through the bridge.
203
+
204
+ Ask me the same framing questions as a normal agent setup — you can ask them all at once:
205
+
206
+ 1. **Role:** What should this agent do? (coach, coding helper, research agent, etc.)
207
+ 2. **Personality:** Tone and style in chat.
208
+ 3. **Language:** Primary language for conversation.
209
+ 4. **Voice:** Should it send voice replies through Mutiro TTS? (if yes, pick a voice — same IDs as the Mutiro create-agent guide: `en-US-Chirp3-HD-Orus`, `en-US-Chirp3-HD-Zephyr`, `pt-BR-Chirp3-HD-Callirrhoe`, etc.)
210
+
211
+ Write the system prompt into the OpenClaw agent's instruction file (check `openclaw agents --help` for the exact path — typically `~/.openclaw/agents/<agent-id>/system.md` or a configured system prompt field). Follow the same structure as Mutiro's create-agent guide:
212
+
213
+ ```markdown
214
+ # <Agent Name> — <One-line role>
215
+
216
+ ## Who You Are
217
+ <identity and personality in 2–3 sentences>
218
+
219
+ ## Your Mission
220
+ <what this agent exists to do>
221
+
222
+ ## How You Communicate
223
+ <tone, length, style — remember replies go through chat>
224
+
225
+ ## What You Do
226
+ <core behaviors>
227
+
228
+ ## Rules
229
+ <hard constraints, especially tool usage>
230
+ ```
231
+
232
+ ---
233
+
234
+ ### Step 8: Enable the Mutiro Channel Tools for the Agent
235
+
236
+ The openclaw-brain plugin ships three extra agent tools on top of the built-in reply surface:
237
+
238
+ | Tool | Purpose |
239
+ |------|---------|
240
+ | `mutiro_send_voice_message` | Reply with a host-synthesized voice message (TTS stays inside Mutiro). |
241
+ | `mutiro_send_card` | Send an interactive A2UI card (v0.8 JSONL). |
242
+ | `mutiro_forward_message` | Forward an existing message to another conversation or user. |
243
+
244
+ These are **channel-scoped agent tools**. They live in a different registry from regular plugin tools, which means the `alsoAllow` list has to match the tool names exactly or via a tool-name glob — group names like `mutiro` or `group:plugins` silently block.
245
+
246
+ Correct forms:
247
+
248
+ ```yaml
249
+ tools:
250
+ profile: messaging # baseline: message, sessions_*, session_status
251
+ alsoAllow:
252
+ - "mutiro*" # glob — enables all Mutiro tools
253
+ # or, explicitly:
254
+ - mutiro_send_voice_message
255
+ - mutiro_send_card
256
+ - mutiro_forward_message
257
+ ```
258
+
259
+ Apply that to the agent's config (use `openclaw agents ...` or edit the agent YAML, depending on how the agent was set up). If I skip this step the agent can still reply with plain text but voice/card/forward tools will be unavailable.
260
+
261
+ ---
262
+
263
+ ### Step 9: Start OpenClaw
264
+
265
+ ```bash
266
+ openclaw gateway run
267
+ ```
268
+
269
+ Watch the logs for these signals:
270
+
271
+ - `channel=mutiro account=default started` — the plugin spawned `mutiro agent host --mode=bridge`.
272
+ - `bridge handshake ok` — `session.initialize` and `subscription.set` completed.
273
+ - No `Handshake failed` or `Host error` lines.
274
+
275
+ If this is a local checkout and new source files were added recently, force a rebuild:
276
+
277
+ ```bash
278
+ OPENCLAW_FORCE_BUILD=1 openclaw gateway run
279
+ ```
280
+
281
+ OpenClaw runs from its built output — dirty-tree detection only looks at `.ts`/`.js` files, so brand-new files in the plugin may not trigger a rebuild on their own.
282
+
283
+ ---
284
+
285
+ ### Step 10: Test It
286
+
287
+ Talk to the agent from any Mutiro surface:
288
+
289
+ - **Web app:** https://app.mutiro.com — sign in and open the conversation with the agent
290
+ - **CLI chat:** `mutiro chat` — terminal UI
291
+ - **Mobile:** Mutiro app on iOS and Android
292
+ - **Desktop:** Mutiro desktop app on macOS, Windows, Linux
293
+
294
+ Or send a quick test message from the shell:
295
+
296
+ ```bash
297
+ mutiro user message send <agent-username> "Hello! Who are you?"
298
+ ```
299
+
300
+ Within a second or two I should see:
301
+
302
+ - a typing/thinking signal on the Mutiro UI (from `signal.emit`)
303
+ - the agent reply threaded under my message
304
+ - OpenClaw logs showing `message.observed` → reply dispatch → `message.send` → `turn.end`
305
+
306
+ If no reply lands, jump to the troubleshooting section below.
307
+
308
+ ---
309
+
310
+ ### Step 11: Iterate
311
+
312
+ - **Wrong tone or behavior?** → Edit the OpenClaw system prompt and restart the gateway.
313
+ - **Missing capability?** → Add the tool to the agent's `alsoAllow` list (remember: exact name or `mutiro*` glob for channel tools).
314
+ - **Wrong model?** → Change the default via `openclaw models set-default`.
315
+ - **Agent hangs or double-replies?** → Make sure the built-in Mutiro brain is not also running against the same agent.
316
+
317
+ Restart with `openclaw gateway run` after any config change.
318
+
319
+ ---
320
+
321
+ ### Step 12: Signals and Live Call Handoff
322
+
323
+ OpenClaw's tool activity is forwarded to Mutiro as bridge signals, so Mutiro surfaces "thinking", "web searching", "recalling", "sending voice", etc. in real time while the agent works. The plugin maps 26 OpenClaw tool names to Mutiro `SignalType` enums; anything outside the map falls back to `SIGNAL_TYPE_CUSTOM` with a detail label.
324
+
325
+ For live voice calls, Mutiro sends `task.request` with a compact observed-turn payload and expects a plain-text result. The plugin handles this by accumulating the agent's reply text and returning it as `ChatBridgeTaskResult.text`. It also answers `session.snapshot` from recent messages cached per-conversation so Mutiro can bootstrap the live lane.
326
+
327
+ Voice call **summaries** flow as normal `message.observed` envelopes tagged `live_call`. OpenClaw treats them as regular inbound turns — nothing extra to configure.
328
+
329
+ ---
330
+
331
+ ### Step 13: Troubleshooting
332
+
333
+ These are the six silent-fail gotchas that cause most first-run issues. Walk through them in order:
334
+
335
+ **1. "Unknown target conv_..."** — The plugin exposes a `targetResolver` that recognizes `conv_*` conversation IDs and `@username` direct sends. If you see this error, the plugin probably did not load; check `openclaw plugins list` and rebuild.
336
+
337
+ **2. "Channel mutiro is unavailable for message actions"** — Reactions rely on the plugin's message-action adapter. Same cause as (1) — plugin not registered. Rebuild and restart.
338
+
339
+ **3. Agent can't use `mutiro_send_voice_message`, `mutiro_send_card`, or `mutiro_forward_message`** — The `alsoAllow` list uses the wrong form. Channel agent tools need exact names or `mutiro*` glob. `mutiro` (group name) silently blocks because channel tools use a separate metadata registry.
340
+
341
+ **4. Media upload succeeds but the reply fails with "path not allowed"** — OpenClaw's sandbox rejects any media path outside `~/.openclaw/media/`. Do not stage files to `/tmp/`; use `saveMediaBuffer` (already wired inside the plugin).
342
+
343
+ **5. New plugin source files are ignored** — The gateway runs from `dist/`, and dirty-tree detection only inspects `.ts`/`.js`. Force a rebuild with `OPENCLAW_FORCE_BUILD=1 openclaw gateway run` after adding new files.
344
+
345
+ **6. Gateway loops restarting the channel** — Usually means `startAccount` resolved early and was interpreted as "channel exited". The plugin fixes this by returning a lifecycle `Promise` that only resolves on host exit or abort; if you are on an older version, update.
346
+
347
+ **Log inspection:**
348
+
349
+ ```bash
350
+ openclaw channels status --probe
351
+ openclaw channels logs --channel mutiro
352
+ openclaw doctor
353
+ ```
354
+
355
+ ---
356
+
357
+ ### Step 14: Security
358
+
359
+ OpenClaw-as-brain inherits both sides' risk surface:
360
+
361
+ - Every Mutiro message, forwarded content, voice transcript, and uploaded file is potential prompt-injection input.
362
+ - OpenClaw's tool set defines the blast radius if an injection succeeds.
363
+
364
+ Apply the same Exposure × Blast Radius thinking as the Mutiro create-agent guide:
365
+
366
+ - **Personal agent, only you message it:** defaults are fine. Still careful with forwarded content.
367
+ - **Shared with trusted people:** keep memory writes scoped; prefer per-user workspace isolation.
368
+ - **Open to everyone:** restrict OpenClaw tools to reply-only — no file writes, no memory writes, no web fetch.
369
+ - **Agent fetches untrusted web content:** separate it into a "research" agent (reads web, reports back) and an "action" agent (only takes instructions from you).
370
+
371
+ The lethal combination: (1) ingests untrusted data, (2) takes consequential actions, (3) runs without human oversight. Do not build one agent that is all three.
372
+
373
+ Help me review OpenClaw's `tools.profile` / `tools.alsoAllow` and the Mutiro `allowlist` together — the weakest link decides the real risk.
374
+
375
+ ---
376
+
377
+ ### Reference
378
+
379
+ **OpenClaw commands:**
380
+ - `openclaw plugins list` — show installed plugins
381
+ - `openclaw channels list` — show registered channels
382
+ - `openclaw channels status --probe` — live channel health
383
+ - `openclaw channels logs --channel mutiro` — plugin logs
384
+ - `openclaw config get channels.mutiro` — view bridge config
385
+ - `openclaw gateway run` — start the gateway
386
+ - `openclaw doctor` — diagnose
387
+ - `openclaw agents --help` — agent setup options
388
+
389
+ **Mutiro commands:**
390
+ - `mutiro agents list` — see your agents
391
+ - `mutiro agents get <username>` — agent details
392
+ - `mutiro agents allowlist get <username>` — who can message it
393
+ - `mutiro user message send <agent-username> "<text>"` — send a test message
394
+ - `mutiro agent doctor` — diagnose the Mutiro side
395
+
396
+ **Docs:**
397
+ - OpenClaw: https://openclaw.ai
398
+ - Mutiro: https://mutiro.com
399
+ - Create a Mutiro agent: https://www.mutiro.com/docs/guides/create-agent.md
400
+ - openclaw-brain repo: https://github.com/mutirolabs/openclaw-brain
401
+ ````
package/index.ts ADDED
@@ -0,0 +1,21 @@
1
+ // Plugin entry. Consumed by OpenClaw's bundled channel loader via the
2
+ // `openclaw.extensions` field in package.json.
3
+ //
4
+ // `defineBundledChannelEntry` wires the channel plugin descriptor (loaded
5
+ // from ./src/channel.ts) into OpenClaw's registry. The heavier runtime
6
+ // module (./src/channel.runtime.ts) is loaded lazily from inside the channel
7
+ // plugin itself (via `createLazyRuntimeNamedExport`), so we do not need to
8
+ // register it here as a `PluginRuntime` setter.
9
+
10
+ import { defineBundledChannelEntry } from "openclaw/plugin-sdk/channel-entry-contract";
11
+
12
+ export default defineBundledChannelEntry({
13
+ id: "mutiro",
14
+ name: "Mutiro",
15
+ description: "Mutiro chatbridge channel plugin",
16
+ importMetaUrl: import.meta.url,
17
+ plugin: {
18
+ specifier: "./src/channel.js",
19
+ exportName: "mutiroPlugin",
20
+ },
21
+ });
@@ -0,0 +1,47 @@
1
+ {
2
+ "id": "mutiro",
3
+ "channels": ["mutiro"],
4
+ "channelEnvVars": {
5
+ "mutiro": ["MUTIRO_AGENT_API_KEY"]
6
+ },
7
+ "configSchema": {
8
+ "type": "object",
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "agentDir": {
12
+ "type": "string",
13
+ "description": "Single-account shortcut: absolute path to the Mutiro agent workspace."
14
+ },
15
+ "clientName": {
16
+ "type": "string",
17
+ "description": "Identifier sent to the host in session.initialize."
18
+ },
19
+ "requestedOptionalCapabilities": {
20
+ "type": "array",
21
+ "items": { "type": "string" },
22
+ "description": "Optional capabilities advertised in session.initialize."
23
+ },
24
+ "enabled": {
25
+ "type": "boolean"
26
+ },
27
+ "accounts": {
28
+ "type": "object",
29
+ "additionalProperties": {
30
+ "type": "object",
31
+ "additionalProperties": false,
32
+ "required": ["agentDir"],
33
+ "properties": {
34
+ "agentDir": { "type": "string" },
35
+ "clientName": { "type": "string" },
36
+ "requestedOptionalCapabilities": {
37
+ "type": "array",
38
+ "items": { "type": "string" }
39
+ },
40
+ "enabled": { "type": "boolean" },
41
+ "name": { "type": "string" }
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@mutirolabs/openclaw-brain",
3
+ "version": "0.1.0",
4
+ "description": "OpenClaw channel plugin that drives a Mutiro agent over chatbridge. OpenClaw becomes the brain; Mutiro stays the messaging surface.",
5
+ "type": "module",
6
+ "license": "ISC",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/mutirolabs/openclaw-brain.git"
10
+ },
11
+ "homepage": "https://github.com/mutirolabs/openclaw-brain#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/mutirolabs/openclaw-brain/issues"
14
+ },
15
+ "scripts": {
16
+ "check": "tsc -p tsconfig.json --noEmit",
17
+ "gateway": "openclaw gateway run",
18
+ "prepublishOnly": "npm run check"
19
+ },
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "keywords": [
24
+ "mutiro",
25
+ "chatbridge",
26
+ "openclaw",
27
+ "channel",
28
+ "plugin",
29
+ "agent"
30
+ ],
31
+ "files": [
32
+ "index.ts",
33
+ "src",
34
+ "docs",
35
+ "openclaw.plugin.json",
36
+ "README.md",
37
+ "LICENSE",
38
+ "CHANGELOG.md"
39
+ ],
40
+ "engines": {
41
+ "node": ">=22"
42
+ },
43
+ "dependencies": {
44
+ "@sinclair/typebox": "^0.34.49"
45
+ },
46
+ "peerDependencies": {
47
+ "openclaw": ">=2026.4.10"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "openclaw": {
51
+ "optional": true
52
+ }
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^22.0.0",
56
+ "openclaw": "^2026.4.15",
57
+ "typescript": "^5.6.0"
58
+ },
59
+ "openclaw": {
60
+ "extensions": [
61
+ "./index.ts"
62
+ ],
63
+ "channel": {
64
+ "id": "mutiro",
65
+ "label": "Mutiro",
66
+ "selectionLabel": "Mutiro (plugin)",
67
+ "docsPath": "/channels/mutiro",
68
+ "docsLabel": "mutiro",
69
+ "blurb": "chatbridge channel; configure a Mutiro agent directory to enable.",
70
+ "order": 80,
71
+ "quickstartAllowFrom": true
72
+ },
73
+ "install": {
74
+ "npmSpec": "@mutirolabs/openclaw-brain",
75
+ "defaultChoice": "npm",
76
+ "minHostVersion": ">=2026.4.10"
77
+ }
78
+ }
79
+ }
package/src/actions.ts ADDED
@@ -0,0 +1,53 @@
1
+ // Message-action adapter for the shared `message` tool. Teaches OpenClaw
2
+ // which actions our plugin handles (react, forward) and dispatches them
3
+ // into the bridge via `channel.runtime.ts`. Without this adapter the tool
4
+ // rejects with "Channel mutiro is unavailable for message actions".
5
+ //
6
+ // Kept compact: `describeMessageTool` returns a fixed action list, and
7
+ // `handleAction` does a dynamic import so the heavy runtime stays off the
8
+ // hot plugin-registration path.
9
+
10
+ import type {
11
+ ChannelMessageActionAdapter,
12
+ ChannelMessageActionContext,
13
+ ChannelMessageActionName,
14
+ } from "openclaw/plugin-sdk/channel-contract";
15
+
16
+ const MUTIRO_HANDLED_ACTIONS: readonly ChannelMessageActionName[] = [
17
+ "react",
18
+ ] as const;
19
+
20
+ const MUTIRO_HANDLED_ACTION_SET = new Set<ChannelMessageActionName>(MUTIRO_HANDLED_ACTIONS);
21
+
22
+ const readStringArg = (
23
+ params: Record<string, unknown>,
24
+ ...keys: string[]
25
+ ): string | undefined => {
26
+ for (const key of keys) {
27
+ const value = params[key];
28
+ if (typeof value === "string") {
29
+ const trimmed = value.trim();
30
+ if (trimmed) return trimmed;
31
+ }
32
+ }
33
+ return undefined;
34
+ };
35
+
36
+ export const mutiroMessageActions: ChannelMessageActionAdapter = {
37
+ describeMessageTool: () => ({
38
+ actions: MUTIRO_HANDLED_ACTIONS,
39
+ capabilities: [],
40
+ }),
41
+
42
+ supportsAction: ({ action }) => MUTIRO_HANDLED_ACTION_SET.has(action),
43
+
44
+ handleAction: async (ctx: ChannelMessageActionContext) => {
45
+ const { handleMutiroMessageAction } = await import("./channel.runtime.js");
46
+ return handleMutiroMessageAction({
47
+ action: ctx.action,
48
+ params: ctx.params,
49
+ accountId: ctx.accountId ?? undefined,
50
+ readStringArg,
51
+ });
52
+ },
53
+ };