Nanobot Lessons¶
When to read: before debugging nanobot tool calls, image/vision issues, MCP failures, or workspace rule edits. Cross-cutting lessons live in [[homelab-deploy-debug-patterns]].
Meta-pattern: MCP tools run cross-container¶
The #1 source of "tool failed mysteriously": an MCP server (e.g. mcp_litellm_minimax-understand_image) runs on a different container than the nanobot caller. Tool description says "accepts local file path" but the file must be visible from where the MCP server runs, not from nanobot.
| MCP tool | Runs on | Sees nanobot's /home/nanobot/...? |
|---|---|---|
mcp_litellm_minimax-understand_image |
LiteLLM host container (litellm-litellm-1) |
❌ No — separate filesystem |
mcp_litellm_crawl4ai-* |
LiteLLM host container | n/a (URL-based, no local files) |
mcp_litellm_qmd-* |
LiteLLM host container | n/a (server-side index) |
mcp_litellm_todoist-* |
LiteLLM host → Todoist API | n/a (SaaS API) |
Symptom: MCP image tool returns Local image file does not exist: /home/nanobot/... even though the file exists in nanobot container.
Test matrix (verified 2026-06-16):
| Input | Result |
|-------|--------|
| Local file path (/home/nanobot/...) | ❌ fail — "file does not exist" |
| Public HTTP URL | ✅ work |
| Data URL (base64 inline) | ❌ fail — JSON arg size limit (~18KB) |
| Docker network HTTP URL (http://<container>:<port>/...) | ✅ work — no SSRF guard for private IPs |
Fix pattern — sidecar HTTP file server: nanobot's compose.yaml ships a nanobot-media busybox sidecar (httpd -f -p 18080 -h /media) on the reverse-proxy network. Local media path /home/nanobot/.nanobot/media/<channel>/<file> → URL http://nanobot-media:18080/<channel>/<file>.
Rule: when an MCP tool returns "file not found" for a local path, the MCP server is on a different container. Convert local paths to HTTP URLs via sidecar before calling.
Workspace rule lifecycle¶
unifiedSession: true means the bot reads RULES.md, AGENTS.md, MEMORY.md, SOUL.md, USER.md, PEOPLES.md once at session start. Edits to these files do not apply to the running session.
Implication: after editing any workspace file, you MUST restart the container (docker restart nanobot-gateway) for the bot to pick up the new rules. Dream cron will commit the edits independently.
Rule redundancy (3 places): when teaching the bot a new pattern, document it in:
RULES.md— operational rule (loaded every session)AGENTS.md— tool routing reference (loaded every session)memory/MEMORY.md— long-term facts (Dream-consolidated)
A rule in only 1 place is insufficient if a stale/conflicting memory row exists (the LLM may trust the memory over the new rule). When the memory is wrong, fix the memory row — don't just add a counter-rule.
Bot failure spiral¶
When an approach fails, the LLM may pivot to worse fallbacks (verified):
- MCP
minimax-understand_imagefail →read_file(binary, no-op) - →
apt-get install tesseract(pollutes container, slow) - →
pip install easyocr(large download) - → custom
python3 urllib.requestscript calling LiteLLM API (often fails on DNS likelitellmnot resolving in nanobot container) - → give up with "không đọc được ảnh"
Detection: watch logs for apt-get, pip install, or custom Python scripts when a single MCP call should suffice. Stop the spiral by cancelling the task (docker restart nanobot-gateway).
Prevention: workspace rules that say "đừng fallback python urllib" + "don't try local paths with MCP". Make the failure cheap.
Log analysis — where to look¶
| Source | What it shows | Limit |
|---|---|---|
km-logs nanobot-gateway -n 200 -t |
Container stdout, tool call signatures (truncated) | Tool args truncated at ~120 chars; full message text cut |
workspace/sessions/unified_default.jsonl |
Full tool_call_id + full response + reasoning_content | Long file, grep for tool name |
workspace/.nanobot/tool-results/unified_default/call_<id>.txt |
Full tool response body (per call) | File ID matches the call ID in JSONL |
km-logs komodo-periphery |
Periphery actions (sync, deploy) | Often empty — periphery doesn't log every action |
Pattern for failed-tool investigation:
- Find the failure timestamp in container logs
- Grep session JSONL for the tool name + timestamp → get tool_call_id + full error response
- For successful calls, read
tool-results/call_<id>.txtfor full payload
Note: container timezone is +07 (Asia/Ho_Chi_Minh) for nanobot logger, but UTC (Z) for Docker log timestamps. Filter accordingly.
Komodo deploy stuck on "deploying: true"¶
km x deploy-stack nanobot (and likely other stacks) can hang indefinitely in deploying: true state even when:
- Compose.yaml is valid (verified by direct
docker compose up) - Periphery is connected to Core
- Image is already pulled
Symptom: km x deploy-stack prints FINISHED in 1.4s: EXECUTION FAILED, then API shows status: InProgress forever; no docker compose process on periphery host.
Workaround — direct compose via periphery:
ssh root@100.68.251.84 "docker exec komodo-periphery sh -c 'cd /etc/komodo/repos/docker-compose/stacks/llm/nanobot && docker compose up -d'"
This is a Core↔Periphery comms issue (auth/network/queue), separate from compose validity. Treat Komodo deploy as best-effort; have direct-SSH fallback ready for time-sensitive deploys.
Quick reference¶
# Check both nanobot containers
ssh root@100.68.251.84 "docker ps --format '{{.Names}}\t{{.Status}}' | grep nanobot"
# Tail logs (UTC Docker + VN nanobot logger)
km-logs nanobot-gateway -n 50 -t
# Find tool calls in session JSONL (UTC timestamps)
ssh root@100.68.251.84 "docker exec nanobot-gateway grep 'understand_image' /home/nanobot/.nanobot/workspace/sessions/unified_default.jsonl | tail -5"
# Read full tool response
ssh root@100.68.251.84 "docker exec nanobot-gateway cat /home/nanobot/.nanobot/workspace/.nanobot/tool-results/unified_default/call_<ID>.txt"
# Test MCP minimax-understand_image directly (via my MCP, from dev container)
# Note: local path fails (cross-container); use HTTP URL
# Direct compose deploy (bypass stuck Komodo Core)
ssh root@100.68.251.84 "docker exec komodo-periphery sh -c 'cd /etc/komodo/repos/docker-compose/stacks/llm/nanobot && docker compose up -d'"
# Restart bot (picks up workspace rule edits + clears old session)
ssh root@100.68.251.84 "docker restart nanobot-gateway"
Related: [[homelab-deploy-debug-patterns]] meta-patterns (silent config divergence, service addressing), [[komodo]] deploy verification, [[custom-image-build-workflow]] Dockerfile patches.
Open questions¶
- Komodo Core↔Periphery comms issue root cause (auth token expiry? websocket reconnect race?) — not investigated, workaround in place.
- Whether nanobot will eventually support native multimodal (image content block to LLM instead of text reference + MCP tool). Upstream feature, tracked in
nanobot/SKILL.md"Source Patches".