@rozek/nanoclaw 0.0.1
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.
- package/.claude/settings.json +1 -0
- package/.claude/skills/add-compact/SKILL.md +135 -0
- package/.claude/skills/add-discord/SKILL.md +203 -0
- package/.claude/skills/add-gmail/SKILL.md +220 -0
- package/.claude/skills/add-image-vision/SKILL.md +94 -0
- package/.claude/skills/add-ollama-tool/SKILL.md +153 -0
- package/.claude/skills/add-parallel/SKILL.md +290 -0
- package/.claude/skills/add-pdf-reader/SKILL.md +104 -0
- package/.claude/skills/add-reactions/SKILL.md +117 -0
- package/.claude/skills/add-slack/SKILL.md +207 -0
- package/.claude/skills/add-telegram/SKILL.md +222 -0
- package/.claude/skills/add-telegram-swarm/SKILL.md +384 -0
- package/.claude/skills/add-voice-transcription/SKILL.md +148 -0
- package/.claude/skills/add-whatsapp/SKILL.md +372 -0
- package/.claude/skills/convert-to-apple-container/SKILL.md +175 -0
- package/.claude/skills/customize/SKILL.md +110 -0
- package/.claude/skills/debug/SKILL.md +349 -0
- package/.claude/skills/get-qodo-rules/SKILL.md +122 -0
- package/.claude/skills/get-qodo-rules/references/output-format.md +41 -0
- package/.claude/skills/get-qodo-rules/references/pagination.md +33 -0
- package/.claude/skills/get-qodo-rules/references/repository-scope.md +26 -0
- package/.claude/skills/qodo-pr-resolver/SKILL.md +326 -0
- package/.claude/skills/qodo-pr-resolver/resources/providers.md +329 -0
- package/.claude/skills/setup/SKILL.md +218 -0
- package/.claude/skills/update-nanoclaw/SKILL.md +235 -0
- package/.claude/skills/update-skills/SKILL.md +130 -0
- package/.claude/skills/use-local-whisper/SKILL.md +152 -0
- package/.claude/skills/x-integration/SKILL.md +417 -0
- package/.claude/skills/x-integration/agent.ts +243 -0
- package/.claude/skills/x-integration/host.ts +159 -0
- package/.claude/skills/x-integration/lib/browser.ts +148 -0
- package/.claude/skills/x-integration/lib/config.ts +62 -0
- package/.claude/skills/x-integration/scripts/like.ts +56 -0
- package/.claude/skills/x-integration/scripts/post.ts +66 -0
- package/.claude/skills/x-integration/scripts/quote.ts +80 -0
- package/.claude/skills/x-integration/scripts/reply.ts +74 -0
- package/.claude/skills/x-integration/scripts/retweet.ts +62 -0
- package/.claude/skills/x-integration/scripts/setup.ts +87 -0
- package/.env.example +1 -0
- package/.github/CODEOWNERS +10 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +14 -0
- package/.github/workflows/bump-version.yml +32 -0
- package/.github/workflows/ci.yml +25 -0
- package/.github/workflows/merge-forward-skills.yml +160 -0
- package/.github/workflows/update-tokens.yml +42 -0
- package/.husky/pre-commit +1 -0
- package/.mcp.json +3 -0
- package/.nvmrc +1 -0
- package/.prettierrc +3 -0
- package/CHANGELOG.md +8 -0
- package/CLAUDE.md +64 -0
- package/CONTRIBUTING.md +23 -0
- package/CONTRIBUTORS.md +15 -0
- package/LICENSE +21 -0
- package/NanoClaw_with_Web-Support.md +325 -0
- package/README.md +261 -0
- package/README_zh.md +200 -0
- package/assets/nanoclaw-favicon.png +0 -0
- package/assets/nanoclaw-icon.png +0 -0
- package/assets/nanoclaw-logo-dark.png +0 -0
- package/assets/nanoclaw-logo.png +0 -0
- package/assets/nanoclaw-profile.jpeg +0 -0
- package/assets/nanoclaw-sales.png +0 -0
- package/assets/social-preview.jpg +0 -0
- package/config-examples/mount-allowlist.json +25 -0
- package/container/Dockerfile +70 -0
- package/container/agent-runner/package.json +21 -0
- package/container/agent-runner/src/index.ts +774 -0
- package/container/agent-runner/src/ipc-mcp-stdio.ts +338 -0
- package/container/agent-runner/tsconfig.json +15 -0
- package/container/build.sh +23 -0
- package/container/skills/agent-browser/SKILL.md +159 -0
- package/container/skills/capabilities/SKILL.md +100 -0
- package/container/skills/cwd/SKILL.md +32 -0
- package/container/skills/pwd/SKILL.md +19 -0
- package/container/skills/status/SKILL.md +104 -0
- package/dist/channels/index.d.ts +2 -0
- package/dist/channels/index.d.ts.map +1 -0
- package/dist/channels/index.js +10 -0
- package/dist/channels/index.js.map +1 -0
- package/dist/channels/registry.d.ts +13 -0
- package/dist/channels/registry.d.ts.map +1 -0
- package/dist/channels/registry.js +11 -0
- package/dist/channels/registry.js.map +1 -0
- package/dist/channels/registry.test.d.ts +2 -0
- package/dist/channels/registry.test.d.ts.map +1 -0
- package/dist/channels/registry.test.js +32 -0
- package/dist/channels/registry.test.js.map +1 -0
- package/dist/channels/web.d.ts +2 -0
- package/dist/channels/web.d.ts.map +1 -0
- package/dist/channels/web.js +1843 -0
- package/dist/channels/web.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +182 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +36 -0
- package/dist/config.js.map +1 -0
- package/dist/container-runner.d.ts +44 -0
- package/dist/container-runner.d.ts.map +1 -0
- package/dist/container-runner.js +511 -0
- package/dist/container-runner.js.map +1 -0
- package/dist/container-runner.test.d.ts +2 -0
- package/dist/container-runner.test.d.ts.map +1 -0
- package/dist/container-runner.test.js +150 -0
- package/dist/container-runner.test.js.map +1 -0
- package/dist/container-runtime.d.ts +22 -0
- package/dist/container-runtime.d.ts.map +1 -0
- package/dist/container-runtime.js +96 -0
- package/dist/container-runtime.js.map +1 -0
- package/dist/container-runtime.test.d.ts +2 -0
- package/dist/container-runtime.test.d.ts.map +1 -0
- package/dist/container-runtime.test.js +93 -0
- package/dist/container-runtime.test.js.map +1 -0
- package/dist/credential-proxy.d.ts +21 -0
- package/dist/credential-proxy.d.ts.map +1 -0
- package/dist/credential-proxy.js +95 -0
- package/dist/credential-proxy.js.map +1 -0
- package/dist/credential-proxy.test.d.ts +2 -0
- package/dist/credential-proxy.test.d.ts.map +1 -0
- package/dist/credential-proxy.test.js +134 -0
- package/dist/credential-proxy.test.js.map +1 -0
- package/dist/db.d.ts +115 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +549 -0
- package/dist/db.js.map +1 -0
- package/dist/db.test.d.ts +2 -0
- package/dist/db.test.d.ts.map +1 -0
- package/dist/db.test.js +360 -0
- package/dist/db.test.js.map +1 -0
- package/dist/env.d.ts +8 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +42 -0
- package/dist/env.js.map +1 -0
- package/dist/formatting.test.d.ts +2 -0
- package/dist/formatting.test.d.ts.map +1 -0
- package/dist/formatting.test.js +183 -0
- package/dist/formatting.test.js.map +1 -0
- package/dist/group-folder.d.ts +5 -0
- package/dist/group-folder.d.ts.map +1 -0
- package/dist/group-folder.js +44 -0
- package/dist/group-folder.js.map +1 -0
- package/dist/group-folder.test.d.ts +2 -0
- package/dist/group-folder.test.d.ts.map +1 -0
- package/dist/group-folder.test.js +29 -0
- package/dist/group-folder.test.js.map +1 -0
- package/dist/group-queue.d.ts +40 -0
- package/dist/group-queue.d.ts.map +1 -0
- package/dist/group-queue.js +276 -0
- package/dist/group-queue.js.map +1 -0
- package/dist/group-queue.test.d.ts +2 -0
- package/dist/group-queue.test.d.ts.map +1 -0
- package/dist/group-queue.test.js +341 -0
- package/dist/group-queue.test.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +592 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc-auth.test.d.ts +2 -0
- package/dist/ipc-auth.test.d.ts.map +1 -0
- package/dist/ipc-auth.test.js +434 -0
- package/dist/ipc-auth.test.js.map +1 -0
- package/dist/ipc.d.ts +32 -0
- package/dist/ipc.d.ts.map +1 -0
- package/dist/ipc.js +311 -0
- package/dist/ipc.js.map +1 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +14 -0
- package/dist/logger.js.map +1 -0
- package/dist/mount-security.d.ts +34 -0
- package/dist/mount-security.d.ts.map +1 -0
- package/dist/mount-security.js +325 -0
- package/dist/mount-security.js.map +1 -0
- package/dist/remote-control.d.ts +32 -0
- package/dist/remote-control.d.ts.map +1 -0
- package/dist/remote-control.js +185 -0
- package/dist/remote-control.js.map +1 -0
- package/dist/remote-control.test.d.ts +2 -0
- package/dist/remote-control.test.d.ts.map +1 -0
- package/dist/remote-control.test.js +321 -0
- package/dist/remote-control.test.js.map +1 -0
- package/dist/router.d.ts +8 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +37 -0
- package/dist/router.js.map +1 -0
- package/dist/routing.test.d.ts +2 -0
- package/dist/routing.test.d.ts.map +1 -0
- package/dist/routing.test.js +81 -0
- package/dist/routing.test.js.map +1 -0
- package/dist/sender-allowlist.d.ts +14 -0
- package/dist/sender-allowlist.d.ts.map +1 -0
- package/dist/sender-allowlist.js +79 -0
- package/dist/sender-allowlist.js.map +1 -0
- package/dist/sender-allowlist.test.d.ts +2 -0
- package/dist/sender-allowlist.test.d.ts.map +1 -0
- package/dist/sender-allowlist.test.js +186 -0
- package/dist/sender-allowlist.test.js.map +1 -0
- package/dist/session-commands.d.ts +47 -0
- package/dist/session-commands.d.ts.map +1 -0
- package/dist/session-commands.js +104 -0
- package/dist/session-commands.js.map +1 -0
- package/dist/session-commands.test.d.ts +2 -0
- package/dist/session-commands.test.d.ts.map +1 -0
- package/dist/session-commands.test.js +194 -0
- package/dist/session-commands.test.js.map +1 -0
- package/dist/task-scheduler.d.ts +22 -0
- package/dist/task-scheduler.d.ts.map +1 -0
- package/dist/task-scheduler.js +241 -0
- package/dist/task-scheduler.js.map +1 -0
- package/dist/task-scheduler.test.d.ts +2 -0
- package/dist/task-scheduler.test.d.ts.map +1 -0
- package/dist/task-scheduler.test.js +107 -0
- package/dist/task-scheduler.test.js.map +1 -0
- package/dist/timezone.d.ts +6 -0
- package/dist/timezone.d.ts.map +1 -0
- package/dist/timezone.js +17 -0
- package/dist/timezone.js.map +1 -0
- package/dist/timezone.test.d.ts +2 -0
- package/dist/timezone.test.d.ts.map +1 -0
- package/dist/timezone.test.js +23 -0
- package/dist/timezone.test.js.map +1 -0
- package/dist/types.d.ts +79 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/APPLE-CONTAINER-NETWORKING.md +90 -0
- package/docs/DEBUG_CHECKLIST.md +143 -0
- package/docs/REQUIREMENTS.md +196 -0
- package/docs/SDK_DEEP_DIVE.md +643 -0
- package/docs/SECURITY.md +122 -0
- package/docs/SPEC.md +785 -0
- package/docs/docker-sandboxes.md +359 -0
- package/docs/nanoclaw-architecture-final.md +1063 -0
- package/docs/nanorepo-architecture.md +168 -0
- package/docs/skills-as-branches.md +662 -0
- package/groups/global/CLAUDE.md +58 -0
- package/groups/main/CLAUDE.md +246 -0
- package/launchd/com.nanoclaw.plist +32 -0
- package/package.json +45 -0
- package/repo-tokens/README.md +113 -0
- package/repo-tokens/action.yml +186 -0
- package/repo-tokens/badge.svg +23 -0
- package/repo-tokens/examples/green.svg +14 -0
- package/repo-tokens/examples/red.svg +14 -0
- package/repo-tokens/examples/yellow-green.svg +14 -0
- package/repo-tokens/examples/yellow.svg +14 -0
- package/scripts/run-migrations.ts +105 -0
- package/setup/container.ts +144 -0
- package/setup/environment.test.ts +121 -0
- package/setup/environment.ts +94 -0
- package/setup/groups.ts +229 -0
- package/setup/index.ts +58 -0
- package/setup/mounts.ts +115 -0
- package/setup/platform.test.ts +120 -0
- package/setup/platform.ts +132 -0
- package/setup/register.test.ts +257 -0
- package/setup/register.ts +177 -0
- package/setup/service.test.ts +187 -0
- package/setup/service.ts +362 -0
- package/setup/status.ts +16 -0
- package/setup/verify.ts +192 -0
- package/setup.sh +161 -0
- package/src/channels/index.ts +15 -0
- package/src/channels/registry.test.ts +42 -0
- package/src/channels/registry.ts +32 -0
- package/src/channels/web.ts +1931 -0
- package/src/cli.ts +209 -0
- package/src/config.ts +73 -0
- package/src/container-runner.test.ts +210 -0
- package/src/container-runner.ts +768 -0
- package/src/container-runtime.test.ts +149 -0
- package/src/container-runtime.ts +127 -0
- package/src/credential-proxy.test.ts +192 -0
- package/src/credential-proxy.ts +125 -0
- package/src/db.test.ts +484 -0
- package/src/db.ts +803 -0
- package/src/env.ts +42 -0
- package/src/formatting.test.ts +256 -0
- package/src/group-folder.test.ts +43 -0
- package/src/group-folder.ts +44 -0
- package/src/group-queue.test.ts +484 -0
- package/src/group-queue.ts +379 -0
- package/src/index.ts +832 -0
- package/src/ipc-auth.test.ts +679 -0
- package/src/ipc.ts +461 -0
- package/src/logger.ts +16 -0
- package/src/mount-security.ts +419 -0
- package/src/remote-control.test.ts +397 -0
- package/src/remote-control.ts +224 -0
- package/src/router.ts +52 -0
- package/src/routing.test.ts +170 -0
- package/src/sender-allowlist.test.ts +216 -0
- package/src/sender-allowlist.ts +128 -0
- package/src/session-commands.test.ts +247 -0
- package/src/session-commands.ts +163 -0
- package/src/task-scheduler.test.ts +129 -0
- package/src/task-scheduler.ts +328 -0
- package/src/timezone.test.ts +29 -0
- package/src/timezone.ts +16 -0
- package/src/types.ts +109 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +7 -0
- package/vitest.skills.config.ts +7 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-ollama-tool
|
|
3
|
+
description: Add Ollama MCP server so the container agent can call local models for cheaper/faster tasks like summarization, translation, or general queries.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Add Ollama Integration
|
|
7
|
+
|
|
8
|
+
This skill adds a stdio-based MCP server that exposes local Ollama models as tools for the container agent. Claude remains the orchestrator but can offload work to local models.
|
|
9
|
+
|
|
10
|
+
Tools added:
|
|
11
|
+
- `ollama_list_models` — lists installed Ollama models
|
|
12
|
+
- `ollama_generate` — sends a prompt to a specified model and returns the response
|
|
13
|
+
|
|
14
|
+
## Phase 1: Pre-flight
|
|
15
|
+
|
|
16
|
+
### Check if already applied
|
|
17
|
+
|
|
18
|
+
Check if `container/agent-runner/src/ollama-mcp-stdio.ts` exists. If it does, skip to Phase 3 (Configure).
|
|
19
|
+
|
|
20
|
+
### Check prerequisites
|
|
21
|
+
|
|
22
|
+
Verify Ollama is installed and running on the host:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ollama list
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
If Ollama is not installed, direct the user to https://ollama.com/download.
|
|
29
|
+
|
|
30
|
+
If no models are installed, suggest pulling one:
|
|
31
|
+
|
|
32
|
+
> You need at least one model. I recommend:
|
|
33
|
+
>
|
|
34
|
+
> ```bash
|
|
35
|
+
> ollama pull gemma3:1b # Small, fast (1GB)
|
|
36
|
+
> ollama pull llama3.2 # Good general purpose (2GB)
|
|
37
|
+
> ollama pull qwen3-coder:30b # Best for code tasks (18GB)
|
|
38
|
+
> ```
|
|
39
|
+
|
|
40
|
+
## Phase 2: Apply Code Changes
|
|
41
|
+
|
|
42
|
+
### Ensure upstream remote
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
git remote -v
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If `upstream` is missing, add it:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git remote add upstream https://github.com/qwibitai/nanoclaw.git
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Merge the skill branch
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git fetch upstream skill/ollama-tool
|
|
58
|
+
git merge upstream/skill/ollama-tool
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
This merges in:
|
|
62
|
+
- `container/agent-runner/src/ollama-mcp-stdio.ts` (Ollama MCP server)
|
|
63
|
+
- `scripts/ollama-watch.sh` (macOS notification watcher)
|
|
64
|
+
- Ollama MCP config in `container/agent-runner/src/index.ts` (allowedTools + mcpServers)
|
|
65
|
+
- `[OLLAMA]` log surfacing in `src/container-runner.ts`
|
|
66
|
+
- `OLLAMA_HOST` in `.env.example`
|
|
67
|
+
|
|
68
|
+
If the merge reports conflicts, resolve them by reading the conflicted files and understanding the intent of both sides.
|
|
69
|
+
|
|
70
|
+
### Copy to per-group agent-runner
|
|
71
|
+
|
|
72
|
+
Existing groups have a cached copy of the agent-runner source. Copy the new files:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
for dir in data/sessions/*/agent-runner-src; do
|
|
76
|
+
cp container/agent-runner/src/ollama-mcp-stdio.ts "$dir/"
|
|
77
|
+
cp container/agent-runner/src/index.ts "$dir/"
|
|
78
|
+
done
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Validate code changes
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm run build
|
|
85
|
+
./container/build.sh
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Build must be clean before proceeding.
|
|
89
|
+
|
|
90
|
+
## Phase 3: Configure
|
|
91
|
+
|
|
92
|
+
### Set Ollama host (optional)
|
|
93
|
+
|
|
94
|
+
By default, the MCP server connects to `http://host.docker.internal:11434` (Docker Desktop) with a fallback to `localhost`. To use a custom Ollama host, add to `.env`:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
OLLAMA_HOST=http://your-ollama-host:11434
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Restart the service
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
|
104
|
+
# Linux: systemctl --user restart nanoclaw
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Phase 4: Verify
|
|
108
|
+
|
|
109
|
+
### Test via WhatsApp
|
|
110
|
+
|
|
111
|
+
Tell the user:
|
|
112
|
+
|
|
113
|
+
> Send a message like: "use ollama to tell me the capital of France"
|
|
114
|
+
>
|
|
115
|
+
> The agent should use `ollama_list_models` to find available models, then `ollama_generate` to get a response.
|
|
116
|
+
|
|
117
|
+
### Monitor activity (optional)
|
|
118
|
+
|
|
119
|
+
Run the watcher script for macOS notifications when Ollama is used:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
./scripts/ollama-watch.sh
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Check logs if needed
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
tail -f logs/nanoclaw.log | grep -i ollama
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Look for:
|
|
132
|
+
- `Agent output: ... Ollama ...` — agent used Ollama successfully
|
|
133
|
+
- `[OLLAMA] >>> Generating` — generation started (if log surfacing works)
|
|
134
|
+
- `[OLLAMA] <<< Done` — generation completed
|
|
135
|
+
|
|
136
|
+
## Troubleshooting
|
|
137
|
+
|
|
138
|
+
### Agent says "Ollama is not installed"
|
|
139
|
+
|
|
140
|
+
The agent is trying to run `ollama` CLI inside the container instead of using the MCP tools. This means:
|
|
141
|
+
1. The MCP server wasn't registered — check `container/agent-runner/src/index.ts` has the `ollama` entry in `mcpServers`
|
|
142
|
+
2. The per-group source wasn't updated — re-copy files (see Phase 2)
|
|
143
|
+
3. The container wasn't rebuilt — run `./container/build.sh`
|
|
144
|
+
|
|
145
|
+
### "Failed to connect to Ollama"
|
|
146
|
+
|
|
147
|
+
1. Verify Ollama is running: `ollama list`
|
|
148
|
+
2. Check Docker can reach the host: `docker run --rm curlimages/curl curl -s http://host.docker.internal:11434/api/tags`
|
|
149
|
+
3. If using a custom host, check `OLLAMA_HOST` in `.env`
|
|
150
|
+
|
|
151
|
+
### Agent doesn't use Ollama tools
|
|
152
|
+
|
|
153
|
+
The agent may not know about the tools. Try being explicit: "use the ollama_generate tool with gemma3:1b to answer: ..."
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Add Parallel AI Integration
|
|
2
|
+
|
|
3
|
+
Adds Parallel AI MCP integration to NanoClaw for advanced web research capabilities.
|
|
4
|
+
|
|
5
|
+
## What This Adds
|
|
6
|
+
|
|
7
|
+
- **Quick Search** - Fast web lookups using Parallel Search API (free to use)
|
|
8
|
+
- **Deep Research** - Comprehensive analysis using Parallel Task API (asks permission)
|
|
9
|
+
- **Non-blocking Design** - Uses NanoClaw scheduler for result polling (no container blocking)
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
User must have:
|
|
14
|
+
1. Parallel AI API key from https://platform.parallel.ai
|
|
15
|
+
2. NanoClaw already set up and running
|
|
16
|
+
3. Docker installed and running
|
|
17
|
+
|
|
18
|
+
## Implementation Steps
|
|
19
|
+
|
|
20
|
+
Run all steps automatically. Only pause for user input when explicitly needed.
|
|
21
|
+
|
|
22
|
+
### 1. Get Parallel AI API Key
|
|
23
|
+
|
|
24
|
+
Use `AskUserQuestion: Do you have a Parallel AI API key, or should I help you get one?`
|
|
25
|
+
|
|
26
|
+
**If they have one:**
|
|
27
|
+
Collect it now.
|
|
28
|
+
|
|
29
|
+
**If they need one:**
|
|
30
|
+
Tell them:
|
|
31
|
+
> 1. Go to https://platform.parallel.ai
|
|
32
|
+
> 2. Sign up or log in
|
|
33
|
+
> 3. Navigate to API Keys section
|
|
34
|
+
> 4. Create a new API key
|
|
35
|
+
> 5. Copy the key and paste it here
|
|
36
|
+
|
|
37
|
+
Wait for the API key.
|
|
38
|
+
|
|
39
|
+
### 2. Add API Key to Environment
|
|
40
|
+
|
|
41
|
+
Add `PARALLEL_API_KEY` to `.env`:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Check if .env exists, create if not
|
|
45
|
+
if [ ! -f .env ]; then
|
|
46
|
+
touch .env
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Add PARALLEL_API_KEY if not already present
|
|
50
|
+
if ! grep -q "PARALLEL_API_KEY=" .env; then
|
|
51
|
+
echo "PARALLEL_API_KEY=${API_KEY_FROM_USER}" >> .env
|
|
52
|
+
echo "✓ Added PARALLEL_API_KEY to .env"
|
|
53
|
+
else
|
|
54
|
+
# Update existing key
|
|
55
|
+
sed -i.bak "s/^PARALLEL_API_KEY=.*/PARALLEL_API_KEY=${API_KEY_FROM_USER}/" .env
|
|
56
|
+
echo "✓ Updated PARALLEL_API_KEY in .env"
|
|
57
|
+
fi
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Verify:
|
|
61
|
+
```bash
|
|
62
|
+
grep "PARALLEL_API_KEY" .env | head -c 50
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 3. Update Container Runner
|
|
66
|
+
|
|
67
|
+
Add `PARALLEL_API_KEY` to allowed environment variables in `src/container-runner.ts`:
|
|
68
|
+
|
|
69
|
+
Find the line:
|
|
70
|
+
```typescript
|
|
71
|
+
const allowedVars = ['CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY'];
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Replace with:
|
|
75
|
+
```typescript
|
|
76
|
+
const allowedVars = ['CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY', 'PARALLEL_API_KEY'];
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 4. Configure MCP Servers in Agent Runner
|
|
80
|
+
|
|
81
|
+
Update `container/agent-runner/src/index.ts`:
|
|
82
|
+
|
|
83
|
+
Find the section where `mcpServers` is configured (around line 237-252):
|
|
84
|
+
```typescript
|
|
85
|
+
const mcpServers: Record<string, any> = {
|
|
86
|
+
nanoclaw: ipcMcp
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Add Parallel AI MCP servers after the nanoclaw server:
|
|
91
|
+
```typescript
|
|
92
|
+
const mcpServers: Record<string, any> = {
|
|
93
|
+
nanoclaw: ipcMcp
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// Add Parallel AI MCP servers if API key is available
|
|
97
|
+
const parallelApiKey = process.env.PARALLEL_API_KEY;
|
|
98
|
+
if (parallelApiKey) {
|
|
99
|
+
mcpServers['parallel-search'] = {
|
|
100
|
+
type: 'http', // REQUIRED: Must specify type for HTTP MCP servers
|
|
101
|
+
url: 'https://search-mcp.parallel.ai/mcp',
|
|
102
|
+
headers: {
|
|
103
|
+
'Authorization': `Bearer ${parallelApiKey}`
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
mcpServers['parallel-task'] = {
|
|
107
|
+
type: 'http', // REQUIRED: Must specify type for HTTP MCP servers
|
|
108
|
+
url: 'https://task-mcp.parallel.ai/mcp',
|
|
109
|
+
headers: {
|
|
110
|
+
'Authorization': `Bearer ${parallelApiKey}`
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
log('Parallel AI MCP servers configured');
|
|
114
|
+
} else {
|
|
115
|
+
log('PARALLEL_API_KEY not set, skipping Parallel AI integration');
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Also update the `allowedTools` array to include Parallel MCP tools (around line 242-248):
|
|
120
|
+
```typescript
|
|
121
|
+
allowedTools: [
|
|
122
|
+
'Bash',
|
|
123
|
+
'Read', 'Write', 'Edit', 'Glob', 'Grep',
|
|
124
|
+
'WebSearch', 'WebFetch',
|
|
125
|
+
'mcp__nanoclaw__*',
|
|
126
|
+
'mcp__parallel-search__*',
|
|
127
|
+
'mcp__parallel-task__*'
|
|
128
|
+
],
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 5. Add Usage Instructions to CLAUDE.md
|
|
132
|
+
|
|
133
|
+
Add Parallel AI usage instructions to `groups/main/CLAUDE.md`:
|
|
134
|
+
|
|
135
|
+
Find the "## What You Can Do" section and add after the existing bullet points:
|
|
136
|
+
```markdown
|
|
137
|
+
- Use Parallel AI for web research and deep learning tasks
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Then add a new section after "## What You Can Do":
|
|
141
|
+
```markdown
|
|
142
|
+
## Web Research Tools
|
|
143
|
+
|
|
144
|
+
You have access to two Parallel AI research tools:
|
|
145
|
+
|
|
146
|
+
### Quick Web Search (`mcp__parallel-search__search`)
|
|
147
|
+
**When to use:** Freely use for factual lookups, current events, definitions, recent information, or verifying facts.
|
|
148
|
+
|
|
149
|
+
**Examples:**
|
|
150
|
+
- "Who invented the transistor?"
|
|
151
|
+
- "What's the latest news about quantum computing?"
|
|
152
|
+
- "When was the UN founded?"
|
|
153
|
+
- "What are the top programming languages in 2026?"
|
|
154
|
+
|
|
155
|
+
**Speed:** Fast (2-5 seconds)
|
|
156
|
+
**Cost:** Low
|
|
157
|
+
**Permission:** Not needed - use whenever it helps answer the question
|
|
158
|
+
|
|
159
|
+
### Deep Research (`mcp__parallel-task__create_task_run`)
|
|
160
|
+
**When to use:** Comprehensive analysis, learning about complex topics, comparing concepts, historical overviews, or structured research.
|
|
161
|
+
|
|
162
|
+
**Examples:**
|
|
163
|
+
- "Explain the development of quantum mechanics from 1900-1930"
|
|
164
|
+
- "Compare the literary styles of Hemingway and Faulkner"
|
|
165
|
+
- "Research the evolution of jazz from bebop to fusion"
|
|
166
|
+
- "Analyze the causes of the French Revolution"
|
|
167
|
+
|
|
168
|
+
**Speed:** Slower (1-20 minutes depending on depth)
|
|
169
|
+
**Cost:** Higher (varies by processor tier)
|
|
170
|
+
**Permission:** ALWAYS use `AskUserQuestion` before using this tool
|
|
171
|
+
|
|
172
|
+
**How to ask permission:**
|
|
173
|
+
```
|
|
174
|
+
AskUserQuestion: I can do deep research on [topic] using Parallel's Task API. This will take 2-5 minutes and provide comprehensive analysis with citations. Should I proceed?
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
**After permission - DO NOT BLOCK! Use scheduler instead:**
|
|
178
|
+
|
|
179
|
+
1. Create the task using `mcp__parallel-task__create_task_run`
|
|
180
|
+
2. Get the `run_id` from the response
|
|
181
|
+
3. Create a polling scheduled task using `mcp__nanoclaw__schedule_task`:
|
|
182
|
+
```
|
|
183
|
+
Prompt: "Check Parallel AI task run [run_id] and send results when ready.
|
|
184
|
+
|
|
185
|
+
1. Use the Parallel Task MCP to check the task status
|
|
186
|
+
2. If status is 'completed', extract the results
|
|
187
|
+
3. Send results to user with mcp__nanoclaw__send_message
|
|
188
|
+
4. Use mcp__nanoclaw__complete_scheduled_task to mark this task as done
|
|
189
|
+
|
|
190
|
+
If status is still 'running' or 'pending', do nothing (task will run again in 30s).
|
|
191
|
+
If status is 'failed', send error message and complete the task."
|
|
192
|
+
|
|
193
|
+
Schedule: interval every 30 seconds
|
|
194
|
+
Context mode: isolated
|
|
195
|
+
```
|
|
196
|
+
4. Send acknowledgment with tracking link
|
|
197
|
+
5. Exit immediately - scheduler handles the rest
|
|
198
|
+
|
|
199
|
+
### Choosing Between Them
|
|
200
|
+
|
|
201
|
+
**Use Search when:**
|
|
202
|
+
- Question needs a quick fact or recent information
|
|
203
|
+
- Simple definition or clarification
|
|
204
|
+
- Verifying specific details
|
|
205
|
+
- Current events or news
|
|
206
|
+
|
|
207
|
+
**Use Deep Research (with permission) when:**
|
|
208
|
+
- User wants to learn about a complex topic
|
|
209
|
+
- Question requires analysis or comparison
|
|
210
|
+
- Historical context or evolution of concepts
|
|
211
|
+
- Structured, comprehensive understanding needed
|
|
212
|
+
- User explicitly asks to "research" or "explain in depth"
|
|
213
|
+
|
|
214
|
+
**Default behavior:** Prefer search for most questions. Only suggest deep research when the topic genuinely requires comprehensive analysis.
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 6. Rebuild Container
|
|
218
|
+
|
|
219
|
+
Build the container with updated agent runner:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
./container/build.sh
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Verify the build:
|
|
226
|
+
```bash
|
|
227
|
+
echo '{}' | docker run -i --entrypoint /bin/echo nanoclaw-agent:latest "Container OK"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### 7. Restart Service
|
|
231
|
+
|
|
232
|
+
Rebuild the main app and restart:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npm run build
|
|
236
|
+
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
|
237
|
+
# Linux: systemctl --user restart nanoclaw
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Wait 3 seconds for service to start, then verify:
|
|
241
|
+
```bash
|
|
242
|
+
sleep 3
|
|
243
|
+
launchctl list | grep nanoclaw # macOS
|
|
244
|
+
# Linux: systemctl --user status nanoclaw
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 8. Test Integration
|
|
248
|
+
|
|
249
|
+
Tell the user to test:
|
|
250
|
+
> Send a message to your assistant: `@[YourAssistantName] what's the latest news about AI?`
|
|
251
|
+
>
|
|
252
|
+
> The assistant should use Parallel Search API to find current information.
|
|
253
|
+
>
|
|
254
|
+
> Then try: `@[YourAssistantName] can you research the history of artificial intelligence?`
|
|
255
|
+
>
|
|
256
|
+
> The assistant should ask for permission before using the Task API.
|
|
257
|
+
|
|
258
|
+
Check logs to verify MCP servers loaded:
|
|
259
|
+
```bash
|
|
260
|
+
tail -20 logs/nanoclaw.log
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Look for: `Parallel AI MCP servers configured`
|
|
264
|
+
|
|
265
|
+
## Troubleshooting
|
|
266
|
+
|
|
267
|
+
**Container hangs or times out:**
|
|
268
|
+
- Check that `type: 'http'` is specified in MCP server config
|
|
269
|
+
- Verify API key is correct in .env
|
|
270
|
+
- Check container logs: `cat groups/main/logs/container-*.log | tail -50`
|
|
271
|
+
|
|
272
|
+
**MCP servers not loading:**
|
|
273
|
+
- Ensure PARALLEL_API_KEY is in .env
|
|
274
|
+
- Verify container-runner.ts includes PARALLEL_API_KEY in allowedVars
|
|
275
|
+
- Check agent-runner logs for "Parallel AI MCP servers configured" message
|
|
276
|
+
|
|
277
|
+
**Task polling not working:**
|
|
278
|
+
- Verify scheduled task was created: `sqlite3 store/messages.db "SELECT * FROM scheduled_tasks"`
|
|
279
|
+
- Check task runs: `tail -f logs/nanoclaw.log | grep "scheduled task"`
|
|
280
|
+
- Ensure task prompt includes proper Parallel MCP tool names
|
|
281
|
+
|
|
282
|
+
## Uninstalling
|
|
283
|
+
|
|
284
|
+
To remove Parallel AI integration:
|
|
285
|
+
|
|
286
|
+
1. Remove from .env: `sed -i.bak '/PARALLEL_API_KEY/d' .env`
|
|
287
|
+
2. Revert changes to container-runner.ts and agent-runner/src/index.ts
|
|
288
|
+
3. Remove Web Research Tools section from groups/main/CLAUDE.md
|
|
289
|
+
4. Rebuild: `./container/build.sh && npm run build`
|
|
290
|
+
5. Restart: `launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-pdf-reader
|
|
3
|
+
description: Add PDF reading to NanoClaw agents. Extracts text from PDFs via pdftotext CLI. Handles WhatsApp attachments, URLs, and local files.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Add PDF Reader
|
|
7
|
+
|
|
8
|
+
Adds PDF reading capability to all container agents using poppler-utils (pdftotext/pdfinfo). PDFs sent as WhatsApp attachments are auto-downloaded to the group workspace.
|
|
9
|
+
|
|
10
|
+
## Phase 1: Pre-flight
|
|
11
|
+
|
|
12
|
+
1. Check if `container/skills/pdf-reader/pdf-reader` exists — skip to Phase 3 if already applied
|
|
13
|
+
2. Confirm WhatsApp is installed first (`skill/whatsapp` merged). This skill modifies WhatsApp channel files.
|
|
14
|
+
|
|
15
|
+
## Phase 2: Apply Code Changes
|
|
16
|
+
|
|
17
|
+
### Ensure WhatsApp fork remote
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
git remote -v
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If `whatsapp` is missing, add it:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Merge the skill branch
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git fetch whatsapp skill/pdf-reader
|
|
33
|
+
git merge whatsapp/skill/pdf-reader || {
|
|
34
|
+
git checkout --theirs package-lock.json
|
|
35
|
+
git add package-lock.json
|
|
36
|
+
git merge --continue
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This merges in:
|
|
41
|
+
- `container/skills/pdf-reader/SKILL.md` (agent-facing documentation)
|
|
42
|
+
- `container/skills/pdf-reader/pdf-reader` (CLI script)
|
|
43
|
+
- `poppler-utils` in `container/Dockerfile`
|
|
44
|
+
- PDF attachment download in `src/channels/whatsapp.ts`
|
|
45
|
+
- PDF tests in `src/channels/whatsapp.test.ts`
|
|
46
|
+
|
|
47
|
+
If the merge reports conflicts, resolve them by reading the conflicted files and understanding the intent of both sides.
|
|
48
|
+
|
|
49
|
+
### Validate
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm run build
|
|
53
|
+
npx vitest run src/channels/whatsapp.test.ts
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Rebuild container
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
./container/build.sh
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Restart service
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS
|
|
66
|
+
# Linux: systemctl --user restart nanoclaw
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Phase 3: Verify
|
|
70
|
+
|
|
71
|
+
### Test PDF extraction
|
|
72
|
+
|
|
73
|
+
Send a PDF file in any registered WhatsApp chat. The agent should:
|
|
74
|
+
1. Download the PDF to `attachments/`
|
|
75
|
+
2. Respond acknowledging the PDF
|
|
76
|
+
3. Be able to extract text when asked
|
|
77
|
+
|
|
78
|
+
### Test URL fetching
|
|
79
|
+
|
|
80
|
+
Ask the agent to read a PDF from a URL. It should use `pdf-reader fetch <url>`.
|
|
81
|
+
|
|
82
|
+
### Check logs if needed
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
tail -f logs/nanoclaw.log | grep -i pdf
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Look for:
|
|
89
|
+
- `Downloaded PDF attachment` — successful download
|
|
90
|
+
- `Failed to download PDF attachment` — media download issue
|
|
91
|
+
|
|
92
|
+
## Troubleshooting
|
|
93
|
+
|
|
94
|
+
### Agent says pdf-reader command not found
|
|
95
|
+
|
|
96
|
+
Container needs rebuilding. Run `./container/build.sh` and restart the service.
|
|
97
|
+
|
|
98
|
+
### PDF text extraction is empty
|
|
99
|
+
|
|
100
|
+
The PDF may be scanned (image-based). pdftotext only handles text-based PDFs. Consider using the agent-browser to open the PDF visually instead.
|
|
101
|
+
|
|
102
|
+
### WhatsApp PDF not detected
|
|
103
|
+
|
|
104
|
+
Verify the message has `documentMessage` with `mimetype: application/pdf`. Some file-sharing apps send PDFs as generic files without the correct mimetype.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: add-reactions
|
|
3
|
+
description: Add WhatsApp emoji reaction support — receive, send, store, and search reactions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Add Reactions
|
|
7
|
+
|
|
8
|
+
This skill adds emoji reaction support to NanoClaw's WhatsApp channel: receive and store reactions, send reactions from the container agent via MCP tool, and query reaction history from SQLite.
|
|
9
|
+
|
|
10
|
+
## Phase 1: Pre-flight
|
|
11
|
+
|
|
12
|
+
### Check if already applied
|
|
13
|
+
|
|
14
|
+
Check if `src/status-tracker.ts` exists:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
test -f src/status-tracker.ts && echo "Already applied" || echo "Not applied"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
If already applied, skip to Phase 3 (Verify).
|
|
21
|
+
|
|
22
|
+
## Phase 2: Apply Code Changes
|
|
23
|
+
|
|
24
|
+
### Ensure WhatsApp fork remote
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
git remote -v
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If `whatsapp` is missing, add it:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Merge the skill branch
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git fetch whatsapp skill/reactions
|
|
40
|
+
git merge whatsapp/skill/reactions || {
|
|
41
|
+
git checkout --theirs package-lock.json
|
|
42
|
+
git add package-lock.json
|
|
43
|
+
git merge --continue
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This adds:
|
|
48
|
+
- `scripts/migrate-reactions.ts` (database migration for `reactions` table with composite PK and indexes)
|
|
49
|
+
- `src/status-tracker.ts` (forward-only emoji state machine for message lifecycle signaling, with persistence and retry)
|
|
50
|
+
- `src/status-tracker.test.ts` (unit tests for StatusTracker)
|
|
51
|
+
- `container/skills/reactions/SKILL.md` (agent-facing documentation for the `react_to_message` MCP tool)
|
|
52
|
+
- Reaction support in `src/db.ts`, `src/channels/whatsapp.ts`, `src/types.ts`, `src/ipc.ts`, `src/index.ts`, `src/group-queue.ts`, and `container/agent-runner/src/ipc-mcp-stdio.ts`
|
|
53
|
+
|
|
54
|
+
### Run database migration
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx tsx scripts/migrate-reactions.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Validate code changes
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm test
|
|
64
|
+
npm run build
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
All tests must pass and build must be clean before proceeding.
|
|
68
|
+
|
|
69
|
+
## Phase 3: Verify
|
|
70
|
+
|
|
71
|
+
### Build and restart
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm run build
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Linux:
|
|
78
|
+
```bash
|
|
79
|
+
systemctl --user restart nanoclaw
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
macOS:
|
|
83
|
+
```bash
|
|
84
|
+
launchctl kickstart -k gui/$(id -u)/com.nanoclaw
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Test receiving reactions
|
|
88
|
+
|
|
89
|
+
1. Send a message from your phone
|
|
90
|
+
2. React to it with an emoji on WhatsApp
|
|
91
|
+
3. Check the database:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
sqlite3 store/messages.db "SELECT * FROM reactions ORDER BY timestamp DESC LIMIT 5;"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Test sending reactions
|
|
98
|
+
|
|
99
|
+
Ask the agent to react to a message via the `react_to_message` MCP tool. Check your phone — the reaction should appear on the message.
|
|
100
|
+
|
|
101
|
+
## Troubleshooting
|
|
102
|
+
|
|
103
|
+
### Reactions not appearing in database
|
|
104
|
+
|
|
105
|
+
- Check NanoClaw logs for `Failed to process reaction` errors
|
|
106
|
+
- Verify the chat is registered
|
|
107
|
+
- Confirm the service is running
|
|
108
|
+
|
|
109
|
+
### Migration fails
|
|
110
|
+
|
|
111
|
+
- Ensure `store/messages.db` exists and is accessible
|
|
112
|
+
- If "table reactions already exists", the migration already ran — skip it
|
|
113
|
+
|
|
114
|
+
### Agent can't send reactions
|
|
115
|
+
|
|
116
|
+
- Check IPC logs for `Unauthorized IPC reaction attempt blocked` — the agent can only react in its own group's chat
|
|
117
|
+
- Verify WhatsApp is connected: check logs for connection status
|