Initial commit: workspace setup with skills, memory, config
This commit is contained in:
415
TOOLS.md
Normal file
415
TOOLS.md
Normal file
@@ -0,0 +1,415 @@
|
||||
# TOOLS.md - Local Notes & Tool Syntax
|
||||
|
||||
---
|
||||
|
||||
## 🔧 `read` — Read File Contents
|
||||
|
||||
**Syntax:**
|
||||
```javascript
|
||||
read({ file_path: "/path/to/file"[, offset: N, limit: N] })
|
||||
```
|
||||
|
||||
**When to use:** Read text files or view images (jpg, png, gif, webp).
|
||||
|
||||
**Required:** `file_path` — NEVER use `path`
|
||||
|
||||
**Correct:**
|
||||
```javascript
|
||||
await read({ file_path: "/path/to/file" })
|
||||
await read({ file_path: "/path/to/file", offset: 1, limit: 50 })
|
||||
```
|
||||
|
||||
**Wrong:**
|
||||
```javascript
|
||||
await read({ path: "/path/to/file" }) // ❌ 'path' is wrong, use 'file_path'
|
||||
await read({}) // ❌ missing file_path entirely
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- Output truncated at 2000 lines or 50KB
|
||||
- Use `offset` + `limit` for files >100 lines
|
||||
- Images sent as attachments automatically
|
||||
|
||||
---
|
||||
|
||||
## 🔧 `edit` — Edit File Contents
|
||||
|
||||
**Syntax:**
|
||||
```javascript
|
||||
edit({ file_path: "/path", old_string: "exact text", new_string: "replacement" })
|
||||
```
|
||||
|
||||
**When to use:** Precise text replacement. Old text must match exactly (including whitespace).
|
||||
|
||||
**Required:** BOTH `old_string` AND `new_string` (not `oldText`/`newText`)
|
||||
|
||||
**Correct:**
|
||||
```javascript
|
||||
await edit({
|
||||
file_path: "/path/to/file",
|
||||
old_string: "text to replace",
|
||||
new_string: "replacement text"
|
||||
})
|
||||
```
|
||||
|
||||
**Wrong:**
|
||||
```javascript
|
||||
await edit({ file_path: "/path/file", old_string: "text" }) // ❌ missing new_string
|
||||
await edit({ file_path: "/path/file", new_string: "text" }) // ❌ missing old_string
|
||||
await edit({ file_path: "/path/file", oldText: "x", newText: "y" }) // ❌ wrong param names
|
||||
```
|
||||
|
||||
**Recovery:** After 2 failed edit attempts → use `write` to rewrite the file completely.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 `write` — Write File Contents
|
||||
|
||||
**Syntax:**
|
||||
```javascript
|
||||
write({ file_path: "/path", content: "complete file content" })
|
||||
```
|
||||
|
||||
**When to use:** Creating new files or rewriting entire files after failed edits.
|
||||
|
||||
**Required:** `file_path` AND complete `content` (overwrites everything)
|
||||
|
||||
**Correct:**
|
||||
```javascript
|
||||
await write({
|
||||
file_path: "/path/to/file",
|
||||
content: "complete file content here"
|
||||
})
|
||||
```
|
||||
|
||||
**Wrong:**
|
||||
```javascript
|
||||
await write({ content: "text" }) // ❌ missing file_path
|
||||
await write({ path: "/file", content: "text" }) // ❌ use file_path not path
|
||||
```
|
||||
|
||||
**⚠️ Caution:** Overwrites entire file — make sure you have the full content.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 `exec` — Execute Shell Commands
|
||||
|
||||
**Syntax:**
|
||||
```javascript
|
||||
exec({ command: "shell command"[, timeout: 30, workdir: "/path"] })
|
||||
```
|
||||
|
||||
**When to use:** Run shell commands, background processes, or TTY-required CLIs.
|
||||
|
||||
**Required:** `command`
|
||||
|
||||
**Correct:**
|
||||
```javascript
|
||||
await exec({ command: "ls -la" })
|
||||
await exec({ command: "python3 script.py", timeout: 60 })
|
||||
await exec({ command: "./script.sh", workdir: "/path/to/dir" })
|
||||
```
|
||||
|
||||
**Cron Scripts — CRITICAL:**
|
||||
```python
|
||||
# Always exit 0 for cron jobs
|
||||
import sys
|
||||
sys.exit(0)
|
||||
```
|
||||
|
||||
**Why:** OpenClaw logs non-zero exits as failures. Use stdout presence for signaling:
|
||||
```python
|
||||
if significant_update:
|
||||
print(notification) # Output triggers notification
|
||||
# No output = silent success
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 `browser` — Browser Control
|
||||
|
||||
**Syntax:**
|
||||
```javascript
|
||||
browser({ action: "navigate|snapshot|click|...", targetUrl: "..." })
|
||||
```
|
||||
|
||||
**When to use:** Navigate, screenshot, or interact with web pages.
|
||||
|
||||
**Required:** `action`
|
||||
|
||||
**Requirements:**
|
||||
- Gateway must be running
|
||||
- Chrome extension must be attached (click extension icon on tab)
|
||||
|
||||
**Correct:**
|
||||
```javascript
|
||||
await browser({ action: "navigate", targetUrl: "https://example.com" })
|
||||
await browser({ action: "snapshot" })
|
||||
await browser({ action: "click", ref: "button-name" })
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference Summary
|
||||
|
||||
| Tool | Required Parameters | Common Errors |
|
||||
|------|---------------------|---------------|
|
||||
| `read` | `file_path` | Using `path` |
|
||||
| `edit` | `file_path`, `old_string`, `new_string` | Using `newText`/`oldText`, missing one param |
|
||||
| `write` | `file_path`, `content` | Partial content, missing `file_path` |
|
||||
| `exec` | `command` | Non-zero exit codes for cron |
|
||||
| `browser` | `action` | Using without gateway check |
|
||||
|
||||
**Critical rules:** Use `file_path` not `path`. Use `old_string`/`new_string` not `oldText`/`newText`.
|
||||
|
||||
**Quality over speed. Verify before executing. Get it right.**
|
||||
|
||||
---
|
||||
|
||||
## Unified Search — Perplexity Primary, SearXNG Fallback
|
||||
|
||||
**Primary:** Perplexity API (cloud, AI-curated, paid)
|
||||
**Fallback:** SearXNG (local, raw results, free)
|
||||
|
||||
### Usage
|
||||
```bash
|
||||
# Default: Perplexity primary, SearXNG fallback on error
|
||||
search "your query"
|
||||
|
||||
# Perplexity only (p = perplexity)
|
||||
search p "your query"
|
||||
search perplexity "your query"
|
||||
|
||||
# SearXNG only (local = searxng)
|
||||
search local "your query"
|
||||
search searxng "your query"
|
||||
|
||||
# With citations (Perplexity)
|
||||
search --citations "your query"
|
||||
|
||||
# Pro model for complex queries
|
||||
search --model sonar-pro "your query"
|
||||
search --model sonar-deep-research "comprehensive research"
|
||||
```
|
||||
|
||||
### Models
|
||||
| Model | Best For | Search Context |
|
||||
|-------|----------|----------------|
|
||||
| sonar | Quick answers, simple queries | Low/Medium/High |
|
||||
| sonar-pro | Complex queries, coding | Medium/High |
|
||||
| sonar-reasoning | Step-by-step reasoning | Medium/High |
|
||||
| sonar-deep-research | Comprehensive research | High |
|
||||
|
||||
### When to Use Each
|
||||
- **Perplexity**: Complex queries, research, current events, anything needing synthesis
|
||||
- **SearXNG**: Privacy-sensitive searches, simple factual lookups, bulk operations, rate limit fallback
|
||||
|
||||
### Scripts
|
||||
- **Unified**: `skills/perplexity/scripts/search.py`
|
||||
- **Perplexity-only**: `skills/perplexity/scripts/query.py`
|
||||
|
||||
---
|
||||
|
||||
## Perplexity API
|
||||
|
||||
- **Location**: `/root/.openclaw/workspace/skills/perplexity/`
|
||||
- **Key**: `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`
|
||||
- **Endpoint**: `https://api.perplexity.ai/chat/completions`
|
||||
- **Models**: sonar, sonar-pro, sonar-reasoning, sonar-deep-research
|
||||
- **Format**: OpenAI-compatible
|
||||
- **Cost**: ~$0.005 per query (shown in output)
|
||||
- **Features**: AI-synthesized answers, citations, real-time search
|
||||
- **Note**: Sends queries to Perplexity servers (cloud)
|
||||
|
||||
---
|
||||
|
||||
### Voice/Text Reply Rules
|
||||
- **Voice message received** → Reply with **voice** (using Kimi-XXX.ogg filename)
|
||||
- Transcribe internally for understanding
|
||||
- **DO NOT send transcript text to Telegram**
|
||||
- **DO NOT include any text with voice messages** — voice-only, completely silent text
|
||||
- Reply with voice-only, no text
|
||||
- **Text message received** → Reply with **text**
|
||||
- **Never** send both voice + text for the same reply
|
||||
- **ENFORCED 2026-02-07:** Voice messages must be sent alone without accompanying text
|
||||
|
||||
### Voice Settings
|
||||
- **TTS Provider**: Local Kokoro @ `http://10.0.0.228:8880`
|
||||
- **Voice**: `af_bella` (American Female)
|
||||
- **Filename format**: `Kimi-YYYYMMDD-HHMMSS.ogg`
|
||||
- **Mode**: Voice-only (no text transcript when sending voice)
|
||||
|
||||
### Web Search
|
||||
- **Primary**: Perplexity API (unified search, AI-curated)
|
||||
- **Fallback**: SearXNG (local instance at `http://10.0.0.8:8888/`)
|
||||
- **Manual fallback**: Use `search local "query"` for privacy-sensitive searches
|
||||
- **Browser tool**: Only when gateway running and extension attached
|
||||
|
||||
### Core Values
|
||||
- **Best accuracy** — No compromises on quality
|
||||
- **Best performance** — Optimize for speed where possible
|
||||
- **Privacy first** — Always prioritize privacy in all decisions
|
||||
- **Always research before install** — Search web for details, docs, best practices
|
||||
- **Local docs exception** — If docs are local (OpenClaw, ClawHub), use those first
|
||||
|
||||
### Search Preferences
|
||||
- **Search first** — Try SearXNG before asking clarifying questions
|
||||
- **Prioritize sites**: *(to be filled in)*
|
||||
- GitHub / GitLab — For code, repos, technical docs
|
||||
- Stack Overflow — For programming Q&A
|
||||
- Wikipedia — For general knowledge
|
||||
- Arch Wiki — For Linux/system admin topics
|
||||
- Official docs — project.readthedocs.io, docs.project.org
|
||||
- **Avoid/deprioritize**: *(to be filled in)*
|
||||
- SEO spam sites
|
||||
- Outdated forums (pre-2020 unless historical)
|
||||
- **Search language**: English preferred, unless query is non-English
|
||||
- **Time bias**: Prefer recent results for tech topics, timeless for facts
|
||||
|
||||
### Search-First Sites (Priority Order)
|
||||
When searching, prefer results from:
|
||||
1. **docs.openclaw.ai** / **OpenClaw docs** — OpenClaw documentation
|
||||
2. **clawhub.com** / **ClawHub** — OpenClaw skills registry
|
||||
3. **docs.*.org** / **readthedocs.io** — Official documentation
|
||||
4. **github.com** / **gitlab.com** — Source code, issues, READMEs
|
||||
5. **stackoverflow.com** — Programming solutions
|
||||
6. **wikipedia.org** — General reference
|
||||
7. **archlinux.org/wiki** — Linux/system administration
|
||||
8. **reddit.com/r/* —** Community discussions (for opinions/experiences)
|
||||
9. **news.ycombinator.com** — Tech news and discussions
|
||||
10. **medium.com** / **dev.to** — Developer blogs (verify date)
|
||||
|
||||
## SSH Hosts
|
||||
|
||||
- **epyc-debian-SSH (deb)** — `n8n@10.0.0.38`
|
||||
- Auth: SSH key (no password)
|
||||
- Key: `~/.ssh/id_ed25519`
|
||||
- Sudo password: `passw0rd`
|
||||
- Usage: `ssh n8n@10.0.0.38`
|
||||
- Status: OpenClaw removed 2026-02-07
|
||||
|
||||
- **epyc-debian2-SSH (deb2)** — `n8n@10.0.0.39`
|
||||
- Auth: SSH key (same as deb)
|
||||
- Key: `~/.ssh/id_ed25519`
|
||||
- Sudo password: `passw0rd`
|
||||
- Usage: `ssh n8n@10.0.0.39`
|
||||
|
||||
## Existing Software Stack
|
||||
|
||||
**⚠️ ALREADY INSTALLED — Do not recommend these:**
|
||||
|
||||
- **n8n** — Workflow automation
|
||||
- **ollama** — Local LLM runner
|
||||
- **openclaw** — AI agent platform (this system)
|
||||
- **openwebui** — LLM chat interface
|
||||
- **anythingllm** — RAG/chat with documents
|
||||
- **searxng** — Privacy-focused search engine
|
||||
- **flowise** — Low-code LLM workflow builder
|
||||
- **plex** — Media server
|
||||
- **radarr** — Movie management
|
||||
- **sonarr** — TV show management
|
||||
- **sabnzbd** — Usenet downloader
|
||||
- **comfyui** — Stable Diffusion UI
|
||||
|
||||
**When recommending software, ALWAYS check this list first and omit any matches.**
|
||||
|
||||
## Skills
|
||||
|
||||
### Local Whisper STT
|
||||
- **Location**: `/root/.openclaw/workspace/skills/local-whisper-stt/`
|
||||
- **Purpose**: Transcribe inbound voice messages
|
||||
- **Model**: `base` (CPU-only)
|
||||
- **Usage**: Auto-transcribes when voice message received
|
||||
- **Correct path**: `scripts/transcribe.py` (not root level)
|
||||
|
||||
### Kimi TTS Custom
|
||||
- **Location**: `/root/.openclaw/workspace/skills/kimi-tts-custom/`
|
||||
- **Purpose**: Generate voice with custom filenames and send voice-only replies
|
||||
- **Scripts**:
|
||||
- `scripts/generate_voice.py` — Generate voice file (returns path, does NOT send)
|
||||
- `scripts/voice_reply.py` — Generate + send voice-only reply (USE THIS for voice replies)
|
||||
- **Usage**: `python3 scripts/voice_reply.py <chat_id> "text"`
|
||||
- **⚠️ CRITICAL**: Text reference to voice file does NOT send audio. Must use `voice_reply.py` or proper Telegram API delivery. Generation ≠ Delivery.
|
||||
|
||||
### Qdrant Memory
|
||||
- **Location**: `/root/.openclaw/workspace/skills/qdrant-memory/`
|
||||
- **Mode**: MANUAL ONLY — No automatic storage
|
||||
- **Collections**:
|
||||
- `kimi_memories` (personal) — Identity, rules, preferences, lessons
|
||||
- `kimi_kb` (knowledge base) — Web data, documents, reference materials
|
||||
- **Vector size**: 1024 (snowflake-arctic-embed2)
|
||||
- **Distance**: Cosine
|
||||
- **Qdrant URL**: `http://10.0.0.40:6333`
|
||||
|
||||
**Personal Memory Scripts (kimi_memories):**
|
||||
- `scripts/store_memory.py` — Manual storage with metadata
|
||||
- `scripts/search_memories.py` — Semantic search
|
||||
- `scripts/hybrid_search.py` — Search files + vectors
|
||||
|
||||
**Knowledge Base Scripts (kimi_kb):**
|
||||
- `scripts/kb_store.py` — Store web/docs to KB
|
||||
- `scripts/kb_search.py` — Search knowledge base
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
# Personal memories ("q remember", "q recall")
|
||||
python3 store_memory.py "Memory" --importance high --tags "preference"
|
||||
python3 search_memories.py "voice settings"
|
||||
|
||||
# Knowledge base (manual document/web storage)
|
||||
python3 kb_store.py "Content" --title "X" --domain "Docker" --tags "container"
|
||||
python3 kb_search.py "docker volumes" --domain "Docker"
|
||||
```
|
||||
|
||||
**⚠️ CRITICAL**: Never auto-store. Only when user explicitly requests with "q" prefix.
|
||||
|
||||
## Infrastructure
|
||||
|
||||
### Container Limits
|
||||
- **No GPUs attached** — All ML workloads run on CPU
|
||||
- **Whisper**: Use `tiny` or `base` models for speed
|
||||
|
||||
### Local Services
|
||||
- **Kokoro TTS**: `http://10.0.0.228:8880` (OpenAI-compatible)
|
||||
- **Ollama**: `http://10.0.0.10:11434`
|
||||
- **SearXNG**: `http://10.0.0.8:8888` (web search via curl)
|
||||
- **Qdrant**: `http://10.0.0.40:6333` (vector database for memory + KB)
|
||||
- **Collections**: `kimi_memories` (personal), `kimi_kb` (knowledge base)
|
||||
- **Vector size**: 1024 (snowflake-arctic-embed2)
|
||||
- **Distance**: Cosine similarity
|
||||
- **Redis**: `10.0.0.36:6379` (task queue, available for future use)
|
||||
|
||||
## Cron Jobs
|
||||
|
||||
- **Default:** Always check `openclaw cron list` first when asked about cron jobs
|
||||
- Rob's scheduled tasks live in OpenClaw's cron system, not system crontab
|
||||
- Only check system crontab (`crontab -l`, `/etc/cron.d/`) if specifically asked about system-level jobs
|
||||
|
||||
---
|
||||
|
||||
## Lessons Learned & Workarounds
|
||||
|
||||
### Embedded Session Tool Errors
|
||||
**Issue:** `read tool called without path` errors occur in embedded sessions even when parameter syntax is correct in workspace scripts.
|
||||
|
||||
**Workarounds:**
|
||||
1. **Double-check parameters manually** — Don't trust the model to pass them correctly in embedded contexts
|
||||
2. **Avoid embedded tool calls when possible** — Use workspace scripts instead
|
||||
3. **Edit fails twice → Use write immediately** — Don't retry edit tool more than once
|
||||
4. **Verify file exists before read** — Prevents ENOENT errors
|
||||
5. **No redis-cli in container** — Use Python redis module instead
|
||||
6. **Browser tool unreliable** — Use curl/SearXNG as primary web access
|
||||
|
||||
### Common Parameter Errors to Avoid
|
||||
| Wrong | Right | Notes |
|
||||
|-------|-------|-------|
|
||||
| `path` | `file_path` | Most common error |
|
||||
| `newText`/`oldText` | `new_string`/`new_string` | Edit tool only |
|
||||
| Missing `new_string` | Include both params | Edit requires both |
|
||||
| Using `write` for small edits | Use `edit` first | Edit is safer for small changes |
|
||||
|
||||
### Environment-Specific Gotchas
|
||||
- **Qdrant Python module** — Must use scripts with proper sys.path setup
|
||||
- **Playwright browsers** — Not installed, use curl/SearXNG for web scraping
|
||||
- **Browser gateway** — Requires Chrome extension attached; rarely available
|
||||
- **Redis CLI** — Not available; use `python3 -c "import redis..."` instead
|
||||
Reference in New Issue
Block a user